mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-04-19 16:08:34 +01:00
- [x] Removed ‘Restart Signal’ global menu item
- [x] Change _Click to create contact…_ to _Start conversation…_
- [x] Move global menu (top-left kebab) into OS menu bar,
i.e. **Settings** > **Preferences…**
- [x] Add tests for OS menu bar templates
- [x] Fix bug with **Window** menu on macOS when showing setup options
- [x] Use _Title Case_ for all OS menu bar menu items for consistency
commit dedf7c9af0
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 16:53:42 2018 -0500
Use ‘Title Case’ to be consistent with OS menus
References:
- Apple:
- https://developer.apple.com/macos/human-interface-guidelines/menus/menu-anatomy/#menu-and-menu-item-titles
- https://developer.apple.com/library/content/documentation/FinalCutProX/Conceptual/FxPlugHIG/TextStyleGuidelines/TextStyleGuidelines.html#//apple_ref/doc/uid/TP40013782-CH6-SW1
- https://titlecaseconverter.com/
commit 3286da29b3
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 16:36:50 2018 -0500
Fix bug for macOS ‘Window’ menu with setup options
commit 236a23d1ea
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 16:27:46 2018 -0500
Test menus with included setup options
commit c5d5f5abb8
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 16:10:27 2018 -0500
Move settings (‘Preferences’) into OS-level menu
This reduces our reliance on custom UI until we have more design resources.
commit 027803f8f4
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 16:02:56 2018 -0500
Prepare tests for menu with/without included setup
commit 9e2f006924
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 15:55:46 2018 -0500
Destructure `includeSetup`
commit 6b2a1eccdf
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 15:55:14 2018 -0500
🔤 `createTemplate` `options`
commit c2fecba34b
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 12:49:55 2018 -0500
Test menu for Windows and Linux
commit 60281b1af9
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 12:40:39 2018 -0500
Add `yarn run test-app` command
commit 1a0489919c
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 12:40:29 2018 -0500
Add test for `SignalMenu.createTemplate` on macOS
commit 9638b86c0f
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 12:34:46 2018 -0500
Make `createTemplate` pure
Extracting `options.platform` makes it easier to test without having to
stub `process.platform`.
commit 9c26404892
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 11:47:39 2018 -0500
Extract `locale.load` `appLocale` & `logger` for testability
This allows us to run this code in a non-Electron environment, e.g. Node.js
Mocha test suite.
commit 710b22438d
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 11:46:13 2018 -0500
🔤 npm scripts
commit 9ae22937fb
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 11:45:30 2018 -0500
Use 2-space indendation for `app` module tests
commit 22c26baf61
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 11:22:55 2018 -0500
Prefer named exports
commit 9c95261952
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 11:22:46 2018 -0500
🔤 Organize `require`s
commit 2f144d24d9
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Tue Feb 27 11:13:50 2018 -0500
Remove existing global hamburger menu
This will be replaced by a OS-level ‘Preferences’ menu.
commit f5adb374cb
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Mon Feb 26 18:40:54 2018 -0500
Remove ‘Restart Signal’ menu from settings
Apparently, this is a remnant from the Chrome web application.
commit d7a206bc8e
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Mon Feb 26 17:16:49 2018 -0500
Clarify label for starting a new conversation
When user a enters a number that is not a contact, we prompt them to start a new
conversation.
commit 715a406436
Author: Daniel Gasienica <daniel@gasienica.ch>
Date: Mon Feb 26 16:46:26 2018 -0500
Use ‘Enter name or number’ as prompt’
This follows implementation of Android and recommendation from Alissa.
172 lines
4.9 KiB
JavaScript
172 lines
4.9 KiB
JavaScript
/* global ConversationController: false */
|
|
/* global i18n: false */
|
|
/* global Whisper: false */
|
|
|
|
// eslint-disable-next-line func-names
|
|
(function () {
|
|
'use strict';
|
|
|
|
window.Whisper = window.Whisper || {};
|
|
|
|
const isSearchable = conversation =>
|
|
conversation.isSearchable();
|
|
|
|
Whisper.NewContactView = Whisper.View.extend({
|
|
templateName: 'new-contact',
|
|
className: 'conversation-list-item contact',
|
|
events: {
|
|
click: 'validate',
|
|
},
|
|
initialize() {
|
|
this.listenTo(this.model, 'change', this.render); // auto update
|
|
},
|
|
render_attributes() {
|
|
return {
|
|
number: i18n('startConversation'),
|
|
title: this.model.getNumber(),
|
|
avatar: this.model.getAvatar(),
|
|
};
|
|
},
|
|
validate() {
|
|
if (this.model.isValid()) {
|
|
this.$el.addClass('valid');
|
|
} else {
|
|
this.$el.removeClass('valid');
|
|
}
|
|
},
|
|
});
|
|
|
|
Whisper.ConversationSearchView = Whisper.View.extend({
|
|
className: 'conversation-search',
|
|
initialize(options) {
|
|
this.$input = options.input;
|
|
this.$new_contact = this.$('.new-contact');
|
|
|
|
this.typeahead = new Whisper.ConversationCollection();
|
|
// View to display the matched contacts from typeahead
|
|
this.typeahead_view = new Whisper.ConversationListView({
|
|
collection: new Whisper.ConversationCollection([], {
|
|
comparator(m) { return m.getTitle().toLowerCase(); },
|
|
}),
|
|
});
|
|
this.$el.append(this.typeahead_view.el);
|
|
this.initNewContact();
|
|
// this.listenTo(this.collection, 'reset', this.filterContacts);
|
|
this.pending = Promise.resolve();
|
|
},
|
|
|
|
events: {
|
|
'click .new-contact': 'createConversation',
|
|
},
|
|
|
|
filterContacts() {
|
|
const query = this.$input.val().trim();
|
|
if (query.length) {
|
|
if (this.maybeNumber(query)) {
|
|
this.new_contact_view.model.set('id', query);
|
|
this.new_contact_view.render().$el.show();
|
|
this.new_contact_view.validate();
|
|
this.hideHints();
|
|
} else {
|
|
this.new_contact_view.$el.hide();
|
|
}
|
|
// NOTE: Temporarily allow `then` until we convert the entire file
|
|
// to `async` / `await`:
|
|
/* eslint-disable more/no-then */
|
|
this.pending = this.pending.then(() =>
|
|
this.typeahead.search(query).then(() => {
|
|
this.typeahead_view.collection.reset(this.typeahead.filter(isSearchable));
|
|
}));
|
|
/* eslint-enable more/no-then */
|
|
this.trigger('show');
|
|
} else {
|
|
this.resetTypeahead();
|
|
}
|
|
},
|
|
|
|
initNewContact() {
|
|
if (this.new_contact_view) {
|
|
this.new_contact_view.undelegateEvents();
|
|
this.new_contact_view.$el.hide();
|
|
}
|
|
// Creates a view to display a new contact
|
|
this.new_contact_view = new Whisper.NewContactView({
|
|
el: this.$new_contact,
|
|
model: ConversationController.createTemporary({
|
|
type: 'private',
|
|
}),
|
|
}).render();
|
|
},
|
|
|
|
createConversation() {
|
|
if (this.new_contact_view.model.isValid()) {
|
|
// NOTE: Temporarily allow `then` until we convert the entire file
|
|
// to `async` / `await`:
|
|
// eslint-disable-next-line more/no-then
|
|
ConversationController.getOrCreateAndWait(
|
|
this.new_contact_view.model.id,
|
|
'private'
|
|
).then((conversation) => {
|
|
this.trigger('open', conversation);
|
|
this.initNewContact();
|
|
this.resetTypeahead();
|
|
});
|
|
} else {
|
|
this.new_contact_view.$('.number').text(i18n('invalidNumberError'));
|
|
this.$input.focus();
|
|
}
|
|
},
|
|
|
|
reset() {
|
|
this.delegateEvents();
|
|
this.typeahead_view.delegateEvents();
|
|
this.new_contact_view.delegateEvents();
|
|
this.resetTypeahead();
|
|
},
|
|
|
|
resetTypeahead() {
|
|
this.hideHints();
|
|
this.new_contact_view.$el.hide();
|
|
this.$input.val('').focus();
|
|
if (this.showAllContacts) {
|
|
// NOTE: Temporarily allow `then` until we convert the entire file
|
|
// to `async` / `await`:
|
|
// eslint-disable-next-line more/no-then
|
|
this.typeahead.fetchAlphabetical().then(() => {
|
|
if (this.typeahead.length > 0) {
|
|
this.typeahead_view.collection.reset(this.typeahead.filter(isSearchable));
|
|
} else {
|
|
this.showHints();
|
|
}
|
|
});
|
|
this.trigger('show');
|
|
} else {
|
|
this.typeahead_view.collection.reset([]);
|
|
this.trigger('hide');
|
|
}
|
|
},
|
|
|
|
showHints() {
|
|
if (!this.hintView) {
|
|
this.hintView = new Whisper.HintView({
|
|
className: 'contact placeholder',
|
|
content: i18n('newPhoneNumber'),
|
|
}).render();
|
|
this.hintView.$el.insertAfter(this.$input);
|
|
}
|
|
this.hintView.$el.show();
|
|
},
|
|
|
|
hideHints() {
|
|
if (this.hintView) {
|
|
this.hintView.remove();
|
|
this.hintView = null;
|
|
}
|
|
},
|
|
|
|
maybeNumber(number) {
|
|
return number.replace(/[\s-.()]*/g, '').match(/^\+?[0-9]*$/);
|
|
},
|
|
});
|
|
}());
|