зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1118061-add "caller unavailable" messages to Hello, r=jaws
This commit is contained in:
Родитель
e28a549c00
Коммит
f16996b82f
|
@ -20,6 +20,11 @@ loop.conversationViews = (function(mozL10n) {
|
||||||
// This duplicates a similar function in contacts.jsx that isn't used in the
|
// This duplicates a similar function in contacts.jsx that isn't used in the
|
||||||
// conversation window. If we get too many of these, we might want to consider
|
// conversation window. If we get too many of these, we might want to consider
|
||||||
// finding a logical place for them to be shared.
|
// finding a logical place for them to be shared.
|
||||||
|
|
||||||
|
// XXXdmose this code is already out of sync with the code in contacts.jsx
|
||||||
|
// which, unlike this code, now has unit tests. We should totally do the
|
||||||
|
// above.
|
||||||
|
|
||||||
function _getPreferredEmail(contact) {
|
function _getPreferredEmail(contact) {
|
||||||
// A contact may not contain email addresses, but only a phone number.
|
// A contact may not contain email addresses, but only a phone number.
|
||||||
if (!contact.email || contact.email.length === 0) {
|
if (!contact.email || contact.email.length === 0) {
|
||||||
|
@ -761,6 +766,25 @@ loop.conversationViews = (function(mozL10n) {
|
||||||
return React.createElement("p", {className: "error"}, mozL10n.get("unable_retrieve_url"));
|
return React.createElement("p", {className: "error"}, mozL10n.get("unable_retrieve_url"));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getTitleMessage: function() {
|
||||||
|
var callStateReason =
|
||||||
|
this.props.store.getStoreState("callStateReason");
|
||||||
|
|
||||||
|
if (callStateReason === "reject" || callStateReason === "busy" ||
|
||||||
|
callStateReason === "setup") {
|
||||||
|
var contactDisplayName = _getContactDisplayName(this.props.contact);
|
||||||
|
if (contactDisplayName.length) {
|
||||||
|
return mozL10n.get(
|
||||||
|
"contact_unavailable_title",
|
||||||
|
{"contactName": contactDisplayName});
|
||||||
|
}
|
||||||
|
|
||||||
|
return mozL10n.get("generic_contact_unavailable_title");
|
||||||
|
} else {
|
||||||
|
return mozL10n.get("generic_failure_title");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
retryCall: function() {
|
retryCall: function() {
|
||||||
this.props.dispatcher.dispatch(new sharedActions.RetryCall());
|
this.props.dispatcher.dispatch(new sharedActions.RetryCall());
|
||||||
},
|
},
|
||||||
|
@ -784,7 +808,7 @@ loop.conversationViews = (function(mozL10n) {
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
React.createElement("div", {className: "call-window"},
|
React.createElement("div", {className: "call-window"},
|
||||||
React.createElement("h2", null, mozL10n.get("generic_failure_title")),
|
React.createElement("h2", null, this._getTitleMessage() ),
|
||||||
|
|
||||||
React.createElement("p", {className: "btn-label"}, mozL10n.get("generic_failure_with_reason2")),
|
React.createElement("p", {className: "btn-label"}, mozL10n.get("generic_failure_with_reason2")),
|
||||||
|
|
||||||
|
@ -1048,6 +1072,7 @@ loop.conversationViews = (function(mozL10n) {
|
||||||
CallIdentifierView: CallIdentifierView,
|
CallIdentifierView: CallIdentifierView,
|
||||||
ConversationDetailView: ConversationDetailView,
|
ConversationDetailView: ConversationDetailView,
|
||||||
CallFailedView: CallFailedView,
|
CallFailedView: CallFailedView,
|
||||||
|
_getContactDisplayName: _getContactDisplayName,
|
||||||
GenericFailureView: GenericFailureView,
|
GenericFailureView: GenericFailureView,
|
||||||
IncomingCallView: IncomingCallView,
|
IncomingCallView: IncomingCallView,
|
||||||
IncomingConversationView: IncomingConversationView,
|
IncomingConversationView: IncomingConversationView,
|
||||||
|
|
|
@ -20,6 +20,11 @@ loop.conversationViews = (function(mozL10n) {
|
||||||
// This duplicates a similar function in contacts.jsx that isn't used in the
|
// This duplicates a similar function in contacts.jsx that isn't used in the
|
||||||
// conversation window. If we get too many of these, we might want to consider
|
// conversation window. If we get too many of these, we might want to consider
|
||||||
// finding a logical place for them to be shared.
|
// finding a logical place for them to be shared.
|
||||||
|
|
||||||
|
// XXXdmose this code is already out of sync with the code in contacts.jsx
|
||||||
|
// which, unlike this code, now has unit tests. We should totally do the
|
||||||
|
// above.
|
||||||
|
|
||||||
function _getPreferredEmail(contact) {
|
function _getPreferredEmail(contact) {
|
||||||
// A contact may not contain email addresses, but only a phone number.
|
// A contact may not contain email addresses, but only a phone number.
|
||||||
if (!contact.email || contact.email.length === 0) {
|
if (!contact.email || contact.email.length === 0) {
|
||||||
|
@ -761,6 +766,25 @@ loop.conversationViews = (function(mozL10n) {
|
||||||
return <p className="error">{mozL10n.get("unable_retrieve_url")}</p>;
|
return <p className="error">{mozL10n.get("unable_retrieve_url")}</p>;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getTitleMessage: function() {
|
||||||
|
var callStateReason =
|
||||||
|
this.props.store.getStoreState("callStateReason");
|
||||||
|
|
||||||
|
if (callStateReason === "reject" || callStateReason === "busy" ||
|
||||||
|
callStateReason === "setup") {
|
||||||
|
var contactDisplayName = _getContactDisplayName(this.props.contact);
|
||||||
|
if (contactDisplayName.length) {
|
||||||
|
return mozL10n.get(
|
||||||
|
"contact_unavailable_title",
|
||||||
|
{"contactName": contactDisplayName});
|
||||||
|
}
|
||||||
|
|
||||||
|
return mozL10n.get("generic_contact_unavailable_title");
|
||||||
|
} else {
|
||||||
|
return mozL10n.get("generic_failure_title");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
retryCall: function() {
|
retryCall: function() {
|
||||||
this.props.dispatcher.dispatch(new sharedActions.RetryCall());
|
this.props.dispatcher.dispatch(new sharedActions.RetryCall());
|
||||||
},
|
},
|
||||||
|
@ -784,7 +808,7 @@ loop.conversationViews = (function(mozL10n) {
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div className="call-window">
|
<div className="call-window">
|
||||||
<h2>{mozL10n.get("generic_failure_title")}</h2>
|
<h2>{ this._getTitleMessage() }</h2>
|
||||||
|
|
||||||
<p className="btn-label">{mozL10n.get("generic_failure_with_reason2")}</p>
|
<p className="btn-label">{mozL10n.get("generic_failure_with_reason2")}</p>
|
||||||
|
|
||||||
|
@ -1048,6 +1072,7 @@ loop.conversationViews = (function(mozL10n) {
|
||||||
CallIdentifierView: CallIdentifierView,
|
CallIdentifierView: CallIdentifierView,
|
||||||
ConversationDetailView: ConversationDetailView,
|
ConversationDetailView: ConversationDetailView,
|
||||||
CallFailedView: CallFailedView,
|
CallFailedView: CallFailedView,
|
||||||
|
_getContactDisplayName: _getContactDisplayName,
|
||||||
GenericFailureView: GenericFailureView,
|
GenericFailureView: GenericFailureView,
|
||||||
IncomingCallView: IncomingCallView,
|
IncomingCallView: IncomingCallView,
|
||||||
IncomingConversationView: IncomingConversationView,
|
IncomingConversationView: IncomingConversationView,
|
||||||
|
|
|
@ -279,7 +279,7 @@
|
||||||
.call-window h2 {
|
.call-window h2 {
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
text-align: center;
|
||||||
/* compensate for reset.css overriding this; values borrowed from
|
/* compensate for reset.css overriding this; values borrowed from
|
||||||
Firefox Mac html.css */
|
Firefox Mac html.css */
|
||||||
margin: 0.83em 0;
|
margin: 0.83em 0;
|
||||||
|
|
|
@ -412,6 +412,61 @@ describe("loop.conversationViews", function () {
|
||||||
sinon.assert.calledOnce(fakeAudio.play);
|
sinon.assert.calledOnce(fakeAudio.play);
|
||||||
expect(fakeAudio.loop).to.equal(false);
|
expect(fakeAudio.loop).to.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should show 'something went wrong' when the reason is 'media-fail'",
|
||||||
|
function () {
|
||||||
|
store.setStoreState({callStateReason: "media-fail"});
|
||||||
|
|
||||||
|
view = mountTestComponent({contact: contact});
|
||||||
|
|
||||||
|
sinon.assert.calledWith(document.mozL10n.get, "generic_failure_title");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should show 'contact unavailable' when the reason is 'reject'",
|
||||||
|
function () {
|
||||||
|
store.setStoreState({callStateReason: "reject"});
|
||||||
|
|
||||||
|
view = mountTestComponent({contact: contact});
|
||||||
|
|
||||||
|
sinon.assert.calledWithExactly(document.mozL10n.get,
|
||||||
|
"contact_unavailable_title",
|
||||||
|
{contactName: loop.conversationViews._getContactDisplayName(contact)});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should show 'contact unavailable' when the reason is 'busy'",
|
||||||
|
function () {
|
||||||
|
store.setStoreState({callStateReason: "busy"});
|
||||||
|
|
||||||
|
view = mountTestComponent({contact: contact});
|
||||||
|
|
||||||
|
sinon.assert.calledWithExactly(document.mozL10n.get,
|
||||||
|
"contact_unavailable_title",
|
||||||
|
{contactName: loop.conversationViews._getContactDisplayName(contact)});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should show 'contact unavailable' when the reason is 'setup'",
|
||||||
|
function () {
|
||||||
|
store.setStoreState({callStateReason: "setup"});
|
||||||
|
|
||||||
|
view = mountTestComponent({contact: contact});
|
||||||
|
|
||||||
|
sinon.assert.calledWithExactly(document.mozL10n.get,
|
||||||
|
"contact_unavailable_title",
|
||||||
|
{contactName: loop.conversationViews._getContactDisplayName(contact)});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should display a generic contact unavailable msg when the reason is" +
|
||||||
|
" 'busy' and no display name is available", function() {
|
||||||
|
store.setStoreState({callStateReason: "busy"});
|
||||||
|
var phoneOnlyContact = {
|
||||||
|
tel: [{"pref": true, type: "work", value: ""}]
|
||||||
|
};
|
||||||
|
|
||||||
|
view = mountTestComponent({contact: phoneOnlyContact});
|
||||||
|
|
||||||
|
sinon.assert.calledWith(document.mozL10n.get,
|
||||||
|
"generic_contact_unavailable_title");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("OngoingConversationView", function() {
|
describe("OngoingConversationView", function() {
|
||||||
|
@ -531,7 +586,10 @@ describe("loop.conversationViews", function () {
|
||||||
|
|
||||||
it("should render the CallFailedView when the call state is 'terminated'",
|
it("should render the CallFailedView when the call state is 'terminated'",
|
||||||
function() {
|
function() {
|
||||||
store.setStoreState({callState: CALL_STATES.TERMINATED});
|
store.setStoreState({
|
||||||
|
callState: CALL_STATES.TERMINATED,
|
||||||
|
contact: contact
|
||||||
|
});
|
||||||
|
|
||||||
view = mountTestComponent();
|
view = mountTestComponent();
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,11 @@
|
||||||
var feedbackStore = new loop.store.FeedbackStore(dispatcher, {
|
var feedbackStore = new loop.store.FeedbackStore(dispatcher, {
|
||||||
feedbackClient: stageFeedbackApiClient
|
feedbackClient: stageFeedbackApiClient
|
||||||
});
|
});
|
||||||
|
var conversationStore = new loop.store.ConversationStore(dispatcher, {
|
||||||
|
client: {},
|
||||||
|
mozLoop: navigator.mozLoop,
|
||||||
|
sdkDriver: {}
|
||||||
|
});
|
||||||
|
|
||||||
// Local mocks
|
// Local mocks
|
||||||
|
|
||||||
|
@ -376,13 +381,14 @@
|
||||||
React.createElement(Example, {summary: "Call Failed", dashed: "true",
|
React.createElement(Example, {summary: "Call Failed", dashed: "true",
|
||||||
style: {width: "260px", height: "265px"}},
|
style: {width: "260px", height: "265px"}},
|
||||||
React.createElement("div", {className: "fx-embedded"},
|
React.createElement("div", {className: "fx-embedded"},
|
||||||
React.createElement(CallFailedView, {dispatcher: dispatcher})
|
React.createElement(CallFailedView, {dispatcher: dispatcher, store: conversationStore})
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
React.createElement(Example, {summary: "Call Failed — with call URL error", dashed: "true",
|
React.createElement(Example, {summary: "Call Failed — with call URL error", dashed: "true",
|
||||||
style: {width: "260px", height: "265px"}},
|
style: {width: "260px", height: "265px"}},
|
||||||
React.createElement("div", {className: "fx-embedded"},
|
React.createElement("div", {className: "fx-embedded"},
|
||||||
React.createElement(CallFailedView, {dispatcher: dispatcher, emailLinkError: true})
|
React.createElement(CallFailedView, {dispatcher: dispatcher, emailLinkError: true,
|
||||||
|
store: conversationStore})
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
|
@ -74,6 +74,11 @@
|
||||||
var feedbackStore = new loop.store.FeedbackStore(dispatcher, {
|
var feedbackStore = new loop.store.FeedbackStore(dispatcher, {
|
||||||
feedbackClient: stageFeedbackApiClient
|
feedbackClient: stageFeedbackApiClient
|
||||||
});
|
});
|
||||||
|
var conversationStore = new loop.store.ConversationStore(dispatcher, {
|
||||||
|
client: {},
|
||||||
|
mozLoop: navigator.mozLoop,
|
||||||
|
sdkDriver: {}
|
||||||
|
});
|
||||||
|
|
||||||
// Local mocks
|
// Local mocks
|
||||||
|
|
||||||
|
@ -376,13 +381,14 @@
|
||||||
<Example summary="Call Failed" dashed="true"
|
<Example summary="Call Failed" dashed="true"
|
||||||
style={{width: "260px", height: "265px"}}>
|
style={{width: "260px", height: "265px"}}>
|
||||||
<div className="fx-embedded">
|
<div className="fx-embedded">
|
||||||
<CallFailedView dispatcher={dispatcher} />
|
<CallFailedView dispatcher={dispatcher} store={conversationStore} />
|
||||||
</div>
|
</div>
|
||||||
</Example>
|
</Example>
|
||||||
<Example summary="Call Failed — with call URL error" dashed="true"
|
<Example summary="Call Failed — with call URL error" dashed="true"
|
||||||
style={{width: "260px", height: "265px"}}>
|
style={{width: "260px", height: "265px"}}>
|
||||||
<div className="fx-embedded">
|
<div className="fx-embedded">
|
||||||
<CallFailedView dispatcher={dispatcher} emailLinkError={true} />
|
<CallFailedView dispatcher={dispatcher} emailLinkError={true}
|
||||||
|
store={conversationStore} />
|
||||||
</div>
|
</div>
|
||||||
</Example>
|
</Example>
|
||||||
</Section>
|
</Section>
|
||||||
|
|
|
@ -225,6 +225,12 @@ peer_ended_conversation2=The person you were calling has ended the conversation.
|
||||||
conversation_has_ended=Your conversation has ended.
|
conversation_has_ended=Your conversation has ended.
|
||||||
restart_call=Rejoin
|
restart_call=Rejoin
|
||||||
|
|
||||||
|
## LOCALIZATION NOTE (contact_unavailable_title): The title displayed
|
||||||
|
## when a contact is unavailable. Don't translate the part between {{..}}
|
||||||
|
## because this will be replaced by the contact's name.
|
||||||
|
contact_unavailable_title={{contactName}} is unavailable.
|
||||||
|
generic_contact_unavailable_title=This person is unavailable.
|
||||||
|
|
||||||
generic_failure_title=Something went wrong.
|
generic_failure_title=Something went wrong.
|
||||||
generic_failure_with_reason2=You can try again or email a link to be reached at later.
|
generic_failure_with_reason2=You can try again or email a link to be reached at later.
|
||||||
generic_failure_no_reason2=Would you like to try again?
|
generic_failure_no_reason2=Would you like to try again?
|
||||||
|
|
Загрузка…
Ссылка в новой задаче