Commit f98587b805da63c46cc6810f870c08e333ff5f4d
change language picker into dropdown with full language names
Matt McKegg committed on 9/30/2017, 3:29:42 AMParent: 1aabebc53a78d5dfda5dbeacba5db26ca946d64e
Files changed
locales/en.json | changed |
locales/es.json | changed |
locales/ki.json | changed |
modules/page/html/render/settings.js | changed |
plugs/intl/sync/i18n.js | changed |
locales/en.json | ||
---|---|---|
@@ -1,5 +1,8 @@ | ||
1 | 1 | { |
2 | + "$name": "English", | |
3 | + "es": "Spanish", | |
4 | + "ki": "Kashmiri", | |
2 | 5 | "Patchwork": "Patchwork", |
3 | 6 | "Public": "Public", |
4 | 7 | "Private": "Private", |
5 | 8 | "Write a public message": "Write a public message", |
@@ -108,29 +111,30 @@ | ||
108 | 111 | "Theme": "Theme", |
109 | 112 | "Language": "Language", |
110 | 113 | "Filters": "Filters", |
111 | 114 | " Hide following messages": " Hide following messages", |
112 | - "Cannot display message" : "Cannot display message", | |
113 | - "Search Results:" : "Search Results:", | |
114 | - "Search completed." : "Search completed.", | |
115 | - "result found" : "result found", | |
116 | - "results found" : "results found", | |
117 | - " forked this discussion:" : " forked this discussion:", | |
118 | - "Your Profile" : "Your Profile", | |
119 | - "Choose Profile Image..." : "Choose Profile Image...", | |
120 | - "Choose a name" : "Choose a name", | |
121 | - "Describe yourself (if you want)" : "Describe yourself (if you want)", | |
122 | - "What whould you like to call " : "What whould you like to call ", | |
123 | - "Confirm" : "Confirm", | |
124 | - "self assigned a display image" : "self assigned a display image", | |
125 | - "Like" : "Like", | |
126 | - "Reply" : "Reply", | |
127 | - "unfollowed " : "unfollowed ", | |
128 | - "Untitled Gathering" : "Untitled Gathering", | |
129 | - "Error" : "Error", | |
130 | - "An error occurred while attempting to publish gathering." : "An error occurred while attempting to publish gathering.", | |
131 | - "An error occurred while attempting to redeem invite." : "An error occurred while attempting to redeem invite.", | |
132 | - "OK" : "OK", | |
133 | - "Close" : "Close", | |
134 | - "New Message" : "New Message", | |
135 | - "unsubscribed from " : "unsubscribed from " | |
115 | + "Cannot display message": "Cannot display message", | |
116 | + "Search Results:": "Search Results:", | |
117 | + "Search completed.": "Search completed.", | |
118 | + "result found": "result found", | |
119 | + "results found": "results found", | |
120 | + " forked this discussion:": " forked this discussion:", | |
121 | + "Your Profile": "Your Profile", | |
122 | + "Choose Profile Image...": "Choose Profile Image...", | |
123 | + "Choose a name": "Choose a name", | |
124 | + "Describe yourself (if you want)": "Describe yourself (if you want)", | |
125 | + "What whould you like to call ": "What whould you like to call ", | |
126 | + "Confirm": "Confirm", | |
127 | + "self assigned a display image": "self assigned a display image", | |
128 | + "Like": "Like", | |
129 | + "Reply": "Reply", | |
130 | + "unfollowed ": "unfollowed ", | |
131 | + "Untitled Gathering": "Untitled Gathering", | |
132 | + "Error": "Error", | |
133 | + "An error occurred while attempting to publish gathering.": "An error occurred while attempting to publish gathering.", | |
134 | + "An error occurred while attempting to redeem invite.": "An error occurred while attempting to redeem invite.", | |
135 | + "OK": "OK", | |
136 | + "Close": "Close", | |
137 | + "New Message": "New Message", | |
138 | + "unsubscribed from ": "unsubscribed from ", | |
139 | + "en": "en" | |
136 | 140 | } |
locales/es.json | ||
---|---|---|
@@ -1,5 +1,6 @@ | ||
1 | 1 | { |
2 | + "$name": "el español", | |
2 | 3 | "Patchwork": "Patchwork", |
3 | 4 | "Public": "Público", |
4 | 5 | "Private": "Privado", |
5 | 6 | "Write a public message": "Escribe un mensaje públio", |
@@ -131,6 +132,9 @@ | ||
131 | 132 | "day": "día", |
132 | 133 | "hour": "hora", |
133 | 134 | "minute": "minutos", |
134 | 135 | "second": "segundos", |
135 | - "unsubscribed from ": "desuscrito de " | |
136 | + "unsubscribed from ": "desuscrito de ", | |
137 | + "en": "en", | |
138 | + "es": "es", | |
139 | + "ki": "ki" | |
136 | 140 | } |
locales/ki.json | ||
---|---|---|
@@ -1,5 +1,6 @@ | ||
1 | 1 | { |
2 | + "$name": "कॉशुर, کأشُر", | |
2 | 3 | "Write a public message": "پبلک پیغام لکھنے", |
3 | 4 | "Active Channels": "فعال", |
4 | 5 | "Loading": "لوڈ ہو رہا ہے", |
5 | 6 | "Local": "مقامی", |
@@ -32,6 +33,53 @@ | ||
32 | 33 | "Write a private reply": "نجی جواب", |
33 | 34 | "Write a public reply": "پبلک جواب", |
34 | 35 | "Publishing...": "پبلشنگ ...", |
35 | 36 | "Publish": "شائع", |
36 | - "More Channels...": "More Channels..." | |
37 | -} | |
37 | + "More Channels...": "More Channels...", | |
38 | + "from now": "from now", | |
39 | + "ago": "ago", | |
40 | + "years": "years", | |
41 | + "months": "months", | |
42 | + "weeks": "weeks", | |
43 | + "days": "days", | |
44 | + "hours": "hours", | |
45 | + "minutes": "minutes", | |
46 | + "seconds": "seconds", | |
47 | + "year": "year", | |
48 | + "month": "month", | |
49 | + "week": "week", | |
50 | + "day": "day", | |
51 | + "hour": "hour", | |
52 | + "minute": "minute", | |
53 | + "second": "second", | |
54 | + "replied to this message": "replied to this message", | |
55 | + "in reply to ": "in reply to ", | |
56 | + "Write a private message": "Write a private message", | |
57 | + "Edit Your Profile": "Edit Your Profile", | |
58 | + "Click to unfollow": "Click to unfollow", | |
59 | + "Friends": "Friends", | |
60 | + "Following": "Following", | |
61 | + "Follow Back": "Follow Back", | |
62 | + "Follow": "Follow", | |
63 | + "Followers": "Followers", | |
64 | + "More": "More", | |
65 | + "Gatherings": "Gatherings", | |
66 | + "Extended Network": "Extended Network", | |
67 | + "Settings": "Settings", | |
68 | + "Upgrading database": "Upgrading database", | |
69 | + "Downloading new messages": "Downloading new messages", | |
70 | + "Indexing database": "Indexing database", | |
71 | + "Scuttling...": "Scuttling...", | |
72 | + " has been released.": " has been released.", | |
73 | + " Click here to download and view more info!": " Click here to download and view more info!", | |
74 | + "Self Assigned": "Self Assigned", | |
75 | + "Assigned By": "Assigned By", | |
76 | + "mentioned you": "mentioned you", | |
77 | + "liked this message": "liked this message", | |
78 | + "followed ": "followed ", | |
79 | + "Channels": "Channels", | |
80 | + "Browse All": "Browse All", | |
81 | + "Theme": "Theme", | |
82 | + "Language": "Language", | |
83 | + "Filters": "Filters", | |
84 | + " Hide following messages": " Hide following messages" | |
85 | +} |
modules/page/html/render/settings.js | ||
---|---|---|
@@ -7,21 +7,23 @@ | ||
7 | 7 | exports.needs = nest({ |
8 | 8 | 'settings.obs.get': 'first', |
9 | 9 | 'settings.sync.set': 'first', |
10 | 10 | 'intl.sync.locales': 'first', |
11 | - 'intl.sync.i18n': 'first' | |
11 | + 'intl.sync.i18n': 'first', | |
12 | + 'intl.sync.localeNames': 'first' | |
12 | 13 | }) |
13 | 14 | |
14 | 15 | exports.gives = nest('page.html.render') |
15 | 16 | |
16 | 17 | exports.create = function (api) { |
17 | 18 | return nest('page.html.render', function channel (path) { |
18 | 19 | if (path !== '/settings') return |
19 | 20 | const i18n = api.intl.sync.i18n |
20 | - | |
21 | + | |
21 | 22 | const currentTheme = api.settings.obs.get('patchwork.theme') |
22 | 23 | const currentLang = api.settings.obs.get('patchwork.lang') |
23 | - const langNames = api.intl.sync.locales() | |
24 | + const locales = api.intl.sync.locales() | |
25 | + const localeNameLookup = api.intl.sync.localeNames() | |
24 | 26 | const filterFollowing = api.settings.obs.get('filters.following') |
25 | 27 | |
26 | 28 | var prepend = [ |
27 | 29 | h('PageHeading', [ |
@@ -34,44 +36,41 @@ | ||
34 | 36 | return h('Scroller', { style: { overflow: 'auto' } }, [ |
35 | 37 | h('div.wrapper', [ |
36 | 38 | h('section.prepend', prepend), |
37 | 39 | h('section.content', [ |
40 | + | |
38 | 41 | h('section', [ |
39 | 42 | h('h2', i18n('Theme')), |
40 | - computed(currentTheme, currentTheme => { | |
41 | - return themeNames.map(name => { | |
42 | - const style = currentTheme == name | |
43 | - ? { 'margin-right': '1rem', 'border-color': 'teal' } | |
44 | - : { 'margin-right': '1rem' } | |
45 | - | |
46 | - return h('button', { | |
47 | - 'ev-click': () => api.settings.sync.set({ | |
48 | - patchwork: {theme: name} | |
49 | - }), | |
50 | - style | |
51 | - }, name) | |
43 | + h('select', { | |
44 | + style: { | |
45 | + 'font-size': '120%' | |
46 | + }, | |
47 | + value: currentTheme, | |
48 | + 'ev-change': (ev) => api.settings.sync.set({ | |
49 | + patchwork: {theme: ev.target.value} | |
52 | 50 | }) |
53 | 51 | }, [ |
54 | 52 | themeNames.map(name => h('option', {value: name}, [name])) |
55 | 53 | ]) |
56 | 54 | ]), |
55 | + | |
57 | 56 | h('section', [ |
58 | 57 | h('h2', i18n('Language')), |
59 | - computed(currentLang, currentLang => { | |
60 | - return langNames.map(lang => { | |
61 | - const style = currentLang == lang | |
62 | - ? { 'margin-right': '1rem', 'border-color': 'teal' } | |
63 | - : { 'margin-right': '1rem' } | |
64 | - | |
65 | - return h('button', { | |
66 | - 'ev-click': () => api.settings.sync.set({ | |
67 | - patchwork: {lang: lang} | |
68 | - }), | |
69 | - style | |
70 | - }, lang) | |
58 | + h('select', { | |
59 | + style: { | |
60 | + 'font-size': '120%' | |
61 | + }, | |
62 | + value: currentLang, | |
63 | + 'ev-change': (ev) => api.settings.sync.set({ | |
64 | + patchwork: {lang: ev.target.value} | |
71 | 65 | }) |
72 | - }) | |
66 | + }, [ | |
67 | + locales.map(code => h('option', {value: code}, [ | |
68 | + code.toUpperCase(), ' - ', getLocaleName(code) | |
69 | + ])) | |
70 | + ]) | |
73 | 71 | ]), |
72 | + | |
74 | 73 | h('section', [ |
75 | 74 | h('h2', i18n('Filters')), |
76 | 75 | h('label', [ |
77 | 76 | h('input', { |
@@ -85,6 +84,17 @@ | ||
85 | 84 | ]) |
86 | 85 | ]) |
87 | 86 | ]) |
88 | 87 | ]) |
88 | + | |
89 | + function getLocaleName (code) { | |
90 | + var translated = i18n(code) | |
91 | + var name = localeNameLookup[code] | |
92 | + | |
93 | + if (name !== translated && code !== translated) { | |
94 | + return `${name} (${translated})` | |
95 | + } else { | |
96 | + return name | |
97 | + } | |
98 | + } | |
89 | 99 | }) |
90 | 100 | } |
plugs/intl/sync/i18n.js | ||
---|---|---|
@@ -1,14 +1,15 @@ | ||
1 | 1 | const nest = require('depnest') |
2 | 2 | var { watch } = require('mutant') |
3 | -var appRoot = require('app-root-path'); | |
4 | -var i18nL = require("i18n") | |
3 | +var appRoot = require('app-root-path') | |
4 | +var i18nL = require('i18n') | |
5 | 5 | |
6 | 6 | exports.gives = nest('intl.sync', [ |
7 | 7 | 'locale', |
8 | 8 | 'locales', |
9 | + 'localeNames', | |
9 | 10 | 'i18n', |
10 | - 'time', | |
11 | + 'time' | |
11 | 12 | ]) |
12 | 13 | |
13 | 14 | exports.needs = nest({ |
14 | 15 | 'intl.sync.locale':'first', |
@@ -28,8 +29,9 @@ | ||
28 | 29 | |
29 | 30 | return nest('intl.sync', { |
30 | 31 | locale, |
31 | 32 | locales, |
33 | + localeNames, | |
32 | 34 | i18n, |
33 | 35 | time |
34 | 36 | }) |
35 | 37 | |
@@ -42,9 +44,17 @@ | ||
42 | 44 | function locales (sofar = {}) { |
43 | 45 | return i18nL.getLocales() |
44 | 46 | } |
45 | 47 | |
46 | - //Get translation | |
48 | + function localeNames () { | |
49 | + var names = i18nL.__l('$name') | |
50 | + return locales().reduce((result, item, i) => { | |
51 | + result[item] = names[i] | |
52 | + return result | |
53 | + }, {}) | |
54 | + } | |
55 | + | |
56 | + //Get translation | |
47 | 57 | function i18n (value) { |
48 | 58 | _init() |
49 | 59 | return i18nL.__(value) |
50 | 60 | } |
@@ -79,9 +89,9 @@ | ||
79 | 89 | }); |
80 | 90 | |
81 | 91 | watch(api.settings.obs.get('patchwork.lang',navigator.language), currentLocale => { |
82 | 92 | i18nL.setLocale(getSubLocal(currentLocale)) |
83 | - | |
93 | + | |
84 | 94 | // Only refresh if the language has already been selected once. |
85 | 95 | // This will prevent the update loop |
86 | 96 | if (_locale) { |
87 | 97 | electron.remote.getCurrentWebContents().reloadIgnoringCache() |
Built with git-ssb-web