aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Stefan Malzner <stefan@adlk.io>2017-10-30 10:47:50 +0100
committerLibravatar GitHub <noreply@github.com>2017-10-30 10:47:50 +0100
commit138feede365a074dff4da238ea1313e89bfb1c5d (patch)
tree90f929642daa7969a0bdac7f41172fbb086a3f4f /src
parentAdd onNotify event to let recipes update/change notifications before send them. (diff)
parentMerge pull request #155 from dannyqiu/fix-theme-change (diff)
downloadferdium-app-138feede365a074dff4da238ea1313e89bfb1c5d.tar.gz
ferdium-app-138feede365a074dff4da238ea1313e89bfb1c5d.tar.zst
ferdium-app-138feede365a074dff4da238ea1313e89bfb1c5d.zip
Merge branch 'develop' into notificationTitleFix
Diffstat (limited to 'src')
-rw-r--r--src/actions/service.js1
-rw-r--r--src/containers/settings/ServicesScreen.js2
-rw-r--r--src/environment.js11
-rw-r--r--src/i18n/languages.js2
-rw-r--r--src/i18n/locales/it.json168
-rw-r--r--src/i18n/locales/nb-NO.json169
-rw-r--r--src/lib/Menu.js61
-rw-r--r--src/lib/Tray.js29
-rw-r--r--src/stores/AppStore.js15
-rw-r--r--src/stores/ServicesStore.js5
10 files changed, 430 insertions, 33 deletions
diff --git a/src/actions/service.js b/src/actions/service.js
index cdd4bbf16..ea6ea5acc 100644
--- a/src/actions/service.js
+++ b/src/actions/service.js
@@ -63,6 +63,7 @@ export default {
63 needle: PropTypes.string.isRequired, 63 needle: PropTypes.string.isRequired,
64 }, 64 },
65 resetFilter: {}, 65 resetFilter: {},
66 resetStatus: {},
66 reorder: { 67 reorder: {
67 oldIndex: PropTypes.number.isRequired, 68 oldIndex: PropTypes.number.isRequired,
68 newIndex: PropTypes.number.isRequired, 69 newIndex: PropTypes.number.isRequired,
diff --git a/src/containers/settings/ServicesScreen.js b/src/containers/settings/ServicesScreen.js
index d0580041f..8cfe5efbf 100644
--- a/src/containers/settings/ServicesScreen.js
+++ b/src/containers/settings/ServicesScreen.js
@@ -18,6 +18,7 @@ export default class ServicesScreen extends Component {
18 18
19 componentWillUnmount() { 19 componentWillUnmount() {
20 this.props.actions.service.resetFilter(); 20 this.props.actions.service.resetFilter();
21 this.props.actions.service.resetStatus();
21 } 22 }
22 23
23 deleteService() { 24 deleteService() {
@@ -70,6 +71,7 @@ ServicesScreen.wrappedComponent.propTypes = {
70 toggleService: PropTypes.func.isRequired, 71 toggleService: PropTypes.func.isRequired,
71 filter: PropTypes.func.isRequired, 72 filter: PropTypes.func.isRequired,
72 resetFilter: PropTypes.func.isRequired, 73 resetFilter: PropTypes.func.isRequired,
74 resetStatus: PropTypes.func.isRequired,
73 }).isRequired, 75 }).isRequired,
74 }).isRequired, 76 }).isRequired,
75}; 77};
diff --git a/src/environment.js b/src/environment.js
index e185120c0..7bb2db134 100644
--- a/src/environment.js
+++ b/src/environment.js
@@ -8,7 +8,16 @@ export const isMac = process.platform === 'darwin';
8export const isWindows = process.platform === 'win32'; 8export const isWindows = process.platform === 'win32';
9export const isLinux = process.platform === 'linux'; 9export const isLinux = process.platform === 'linux';
10 10
11export const ctrlKey = isMac ? '⌘' : 'Ctrl'; 11let ctrlShortcutKey;
12if (isMac) {
13 ctrlShortcutKey = '⌘';
14} else if (isWindows) {
15 ctrlShortcutKey = 'Ctrl';
16} else {
17 ctrlShortcutKey = 'Alt';
18}
19
20export const ctrlKey = ctrlShortcutKey;
12 21
13let api; 22let api;
14if (!isDevMode || (isDevMode && useLiveAPI)) { 23if (!isDevMode || (isDevMode && useLiveAPI)) {
diff --git a/src/i18n/languages.js b/src/i18n/languages.js
index 8777cf89a..72d7b26c1 100644
--- a/src/i18n/languages.js
+++ b/src/i18n/languages.js
@@ -10,6 +10,8 @@ module.exports = {
10 pl: 'Polish', 10 pl: 'Polish',
11 ru: 'Русский', 11 ru: 'Русский',
12 ua: 'Українська', 12 ua: 'Українська',
13 it: 'Italian',
13 'es-ES': 'Español - España', 14 'es-ES': 'Español - España',
14 'zh-Hant': 'Chinese (Traditional)', 15 'zh-Hant': 'Chinese (Traditional)',
16 'nb-NO': 'Norsk',
15}; 17};
diff --git a/src/i18n/locales/it.json b/src/i18n/locales/it.json
new file mode 100644
index 000000000..dd87599bb
--- /dev/null
+++ b/src/i18n/locales/it.json
@@ -0,0 +1,168 @@
1{
2 "global.api.unhealthy": "Impossibile connettersi ai servizi online di Franz",
3 "global.notConnectedToTheInternet": "Non sei connesso ad internet.",
4 "welcome.signupButton": "Iscriviti gratis",
5 "welcome.loginButton": "Accedi",
6 "welcome.slogan": "Messagistica che lavora per te",
7 "login.headline": "Accedi",
8 "login.email.label": "Indirizzo email",
9 "login.password.label": "Password",
10 "login.submit.label": "Accedi",
11 "login.invalidCredentials": "Email o password non validi",
12 "login.tokenExpired": "La tua sessione è scaduta, accedi di nuovo per favore.",
13 "login.serverLogout": "La tua sessione è scaduta, accedi di nuovo per favore.",
14 "login.link.signup": "Iscriviti gratis",
15 "login.link.password": "Reimposta password",
16 "password.headline": "Reimposta password",
17 "password.email.label": "Indirizzo email",
18 "password.submit.label": "Invia",
19 "password.noUser": "Non è stato trovato nessun utente con questa email",
20 "password.successInfo": "Per favore controlla la tua email",
21 "password.link.signup": "Iscriviti gratis",
22 "password.link.login": "Accedi",
23 "signup.headline": "Accedi",
24 "signup.firstname.label": "Nome",
25 "signup.lastname.label": "Cognome",
26 "signup.email.label": "Indirizzo email",
27 "signup.company.label": "Azienda",
28 "signup.password.label": "Password",
29 "signup.submit.label": "Registrati",
30 "signup.link.login": "Hai già fatto l'iscrizione? Accedi",
31 "signup.emailDuplicate": "Esiste già un utente con questo indirizzo email",
32 "signup.legal.info": "Iscrivendoti a Franz accetti",
33 "signup.legal.terms": "Termini di servizio",
34 "signup.legal.privacy": "Informativa sulla Privacy",
35 "pricing.headline": "Supporta Franz",
36 "pricing.support.label": "Seleziona il tuo piano di sostegno",
37 "pricing.submit.label": "Voglio sostenere lo sviluppo di Franz",
38 "pricing.link.skipPayment": "Non voglio sostenere lo sviluppo Franz.",
39 "import.headline": "Importa i tuoi servizi di Franz 4",
40 "import.notSupportedHeadline": "Servzi non ancora supportati in Franz 5",
41 "import.submit.label": "Importa servizi",
42 "import.skip.label": "Voglio aggiungere i servizi a mano",
43 "invite.submit.label": "Manda inviti",
44 "invite.headline.friends": "Invita 3 dei tuoi amici o colleghi",
45 "invite.name.label": "Nome",
46 "invite.email.label": "Indirizzo email",
47 "invite.skip.label": "Voglio farlo dopo",
48 "subscription.submit.label": "Voglio sostenere lo sviluppo di Franz",
49 "subscription.paymentSessionError": "Impossibile inizializzare il modulo di pagamento",
50 "subscription.includedFeatures": "La sottoscrizione a pagamento Franz Premium Supporter include",
51 "subscription.features.onpremise": "Agiunge servizi on-premise/hosted come HipChat",
52 "subscription.features.customServices": "Servizi privati per te ed il tuo team",
53 "subscription.features.encryptedSync": "Sincronizzazione sessione crittografata",
54 "subscription.features.vpn": "Supporto di Proxy e VPN",
55 "subscription.features.ads": "Nessuna pubblicità",
56 "subscription.features.comingSoon": "Presto disponibile",
57 "infobar.servicesUpdated": "I tuoi servizi sono stati aggiornati.",
58 "infobar.updateAvailable": "È disponibile un nuovo aggiornamento per Franz.",
59 "infobar.buttonReloadServices": "Ricarica i servizi",
60 "infobar.buttonInstallUpdate": "Riavvia e installa l'aggiornamento",
61 "infobar.requiredRequestsFailed": "Impossibile caricare i servizi e le informazioni dell'utente",
62 "sidebar.settings": "Impostazioni",
63 "services.welcome": "Benvenuto in Franz",
64 "services.getStarted": "Inizia",
65 "settings.account.headline": "Conto",
66 "settings.account.headlineSubscription": "La tua sottoscrizione",
67 "settings.account.headlineUpgrade": "Aggiorna il tuo conto e supporta Franz",
68 "settings.account.headlineInvoices": "Fatture",
69 "settings.account.manageSubscription.label": "Gestisci la tua sottoscrizione",
70 "settings.account.accountType.basic": "Conto Base",
71 "settings.account.accountType.premium": "Conto Premium Supporter",
72 "settings.account.account.editButton": "Modifica conto",
73 "settings.account.invoiceDownload": "Scarica",
74 "settings.account.userInfoRequestFailed": "Impossibile caricare le informazioni dell'utente",
75 "settings.account.tryReloadUserInfoRequest": "Prova ancora",
76 "settings.account.headlineProfile": "Aggiorna profilo",
77 "settings.account.headlineAccount": "Informazioni sul conto",
78 "settings.account.headlinePassword": "Cambia la password",
79 "settings.account.successInfo": "Le tue modifiche sono state salvate",
80 "settings.account.buttonSave": "Aggiorna profilo",
81 "settings.account.mining.thankyou": "Grazie per supportare Franz con la tua potenza di calcolo.",
82 "settings.account.mining.active": "Al momento stai eseguendo {hashes} calcoli al secondo.",
83 "settings.account.mining.moreInformation": "Ottieni piú informazioni",
84 "settings.account.mining.cancel": "Annulla mining",
85 "settings.navigation.availableServices": "Servizi disponibili",
86 "settings.navigation.yourServices": "I tuoi servizi",
87 "settings.navigation.account": "Conto",
88 "settings.navigation.settings": "Impostazioni",
89 "settings.navigation.logout": "Disconnetti",
90 "settings.recipes.headline": "Servizi disponibili",
91 "settings.recipes.mostPopular": "Piú popolari",
92 "settings.recipes.all": "Tutti i servizi",
93 "settings.recipes.dev": "Sviluppo",
94 "settings.recipes.nothingFound": "Mi dispiace, nessuno servizio corrisponde alla tua ricerca.",
95 "settings.recipes.servicesSuccessfulAddedInfo": "Servizio aggiunto con successo",
96 "settings.service.form.saveButton": "Salva servizio",
97 "settings.service.form.deleteButton": "Elimina servizio",
98 "settings.service.form.availableServices": "Servizi disponibili",
99 "settings.service.form.yourServices": "I tuoi servizi",
100 "settings.service.form.addServiceHeadline": "Aggiungi {name}",
101 "settings.service.form.editServiceHeadline": "Modifica {name}",
102 "settings.service.form.tabHosted": "Hosted",
103 "settings.service.form.tabOnPremise": "Self hosted ⭐️",
104 "settings.service.form.customUrlValidationError": "Impossibile validare il server personale {name}.",
105 "settings.service.form.customUrlPremiumInfo": "Per aggiungere servizi self hosted devi avere un conto Franz Premium Supporter.",
106 "settings.service.form.customUrlUpgradeAccount": "Aggiorna il tuo conto",
107 "settings.service.form.indirectMessageInfo": "Riceverai notifiche per tutti i nuovi messaggi in un canale, non solo @username, @channel, @here, ...",
108 "settings.service.error.headline": "Errore",
109 "settings.service.error.goBack": "Torna ai servizi",
110 "settings.service.error.message": "Impossibile caricare le specifiche del servizio.",
111 "settings.services.tooltip.isDisabled": "Il servizio è disabilitato",
112 "settings.services.tooltip.notificationsDisabled": "Le notifiche sono disabilitate",
113 "settings.services.headline": "I tuoi servizi",
114 "settings.services.noServicesAdded": "Non hai ancora aggiunto nessun servizio.",
115 "settings.services.discoverServices": "Trova servizi",
116 "settings.services.updatedInfo": "Le tue modifiche sono state salvate",
117 "settings.services.deletedInfo": "Il servizio è stato eliminato",
118 "settings.app.headline": "Impostazioni",
119 "settings.app.headlineGeneral": "Generale",
120 "settings.app.headlineLanguage": "Lingua",
121 "settings.app.headlineUpdates": "Aggiornamento",
122 "settings.app.buttonSearchForUpdate": "Controlla aggiornamento versione",
123 "settings.app.buttonInstallUpdate": "Riavvia e installa l'aggiornamento",
124 "settings.app.updateStatusSearching": "Sto cercando l'aggiornamento",
125 "settings.app.updateStatusAvailable": "Aggiornamento disponibile, scarico...",
126 "settings.app.updateStatusUpToDate": "You are using the latest version of Franz",
127 "settings.app.form.autoLaunchOnStart": "Lancia Franz all'avvio",
128 "settings.app.form.autoLaunchInBackground": "Apri in background",
129 "settings.app.form.enableSystemTray": "Mostra Franz nella zona delle notifiche di sistema",
130 "settings.app.form.minimizeToSystemTray": "Minimizza Franz nella zona delle notifiche di sistema",
131 "settings.app.form.runInBackground": "Maniteni Franz attivo in background quando chiudi la finestra",
132 "settings.app.form.language": "Lingua",
133 "settings.app.form.beta": "Includi versioni beta",
134 "settings.app.currentVersion": "Versione corrente:",
135 "settings.service.form.name": "Nome",
136 "settings.service.form.enableService": "Abilita servizio",
137 "settings.service.form.enableNotification": "Abilita notifiche",
138 "settings.service.form.team": "Team",
139 "settings.service.form.customUrl": "Server personale",
140 "settings.service.form.indirectMessages": "Mostra il badge del messaggio per tutti i nuovi messaggi",
141 "settings.user.form.firstname": "Nome",
142 "settings.user.form.lastname": "Cognome",
143 "settings.user.form.email": "Email",
144 "settings.user.form.currentPassword": "Password corrente",
145 "settings.user.form.newPassword": "Nuova password",
146 "settings.user.form.accountType.label": "Tipo di conto",
147 "settings.user.form.accountType.individual": "Individuale",
148 "settings.user.form.accountType.non-profit": "Non-Profit",
149 "settings.user.form.accountType.company": "Azienda",
150 "subscription.type.free": "gratis",
151 "subscription.type.month": "mese",
152 "subscription.type.year": "anno",
153 "subscription.type.mining": "Supporta Franz con della potenza di calcolo",
154 "subscription.mining.headline": "Come funziona?",
155 "subscription.mining.experimental": "sperimentale",
156 "subscription.mining.line1": "Abilitando \"Supporta Franz con della potenza di calcolo\",Franz userà circa il 20-50% della tua CPU per fare il mining della criptovaluta Monero che equivale approssimativamente a 5$/anno.",
157 "subscription.mining.line2": "Adatteremo l'utilizzo della CPU in base all tue abitudini di lavoro per non scaricare la tua batteria e rallentare la tua macchina.",
158 "subscription.mining.line3": "Fino a che il mining è attivo, avrai accesso illimitato a tutte le funzionalità del conto Franz Premium Supporter.",
159 "subscription.mining.moreInformation": "Ottieni più informazioni su questo piano.",
160 "subscriptionPopup.buttonCancel": "Annulla",
161 "subscriptionPopup.buttonDone": "Fatto",
162 "tabs.item.reload": "Ricarica",
163 "tabs.item.edit": "Modifica",
164 "tabs.item.disableNotifications": "Disabilita le notifiche",
165 "tabs.item.enableNotification": "Abilita le notifiche",
166 "tabs.item.disableService": "Disabilita servizio",
167 "tabs.item.deleteService": "Elimina servizio"
168}
diff --git a/src/i18n/locales/nb-NO.json b/src/i18n/locales/nb-NO.json
new file mode 100644
index 000000000..976c54787
--- /dev/null
+++ b/src/i18n/locales/nb-NO.json
@@ -0,0 +1,169 @@
1{
2 "global.api.unhealthy": "Kan ikke koble til Franz' tjenester",
3 "global.notConnectedToTheInternet": "Du er ikke koblet til internett.",
4 "welcome.signupButton": "Opprett en gratis konto",
5 "welcome.loginButton": "Logg inn til din konto",
6 "welcome.slogan": "Teksting som funker for deg",
7 "login.headline": "Logg inn",
8 "login.email.label": "Email adresse",
9 "login.password.label": "Passord",
10 "login.submit.label": "Logg inn",
11 "login.invalidCredentials": "Ugyldig email eller passord",
12 "login.tokenExpired": "Din økt utløpte, vennligst logg inn igjen.",
13 "login.serverLogout": "Din økt utløpte, vennligst logg inn igjen.",
14 "login.link.signup": "Opprett en gratis konto",
15 "login.link.password": "Reset passord",
16 "password.headline": "Reset passord",
17 "password.email.label": "Email adresse",
18 "password.submit.label": "Send inn",
19 "password.noUser": "Ingen bruker med den emailen finnes",
20 "password.successInfo": "Vennligst sjekk din email",
21 "password.link.signup": "Opprett en gratis konto",
22 "password.link.login": "Logg inn til din konto",
23 "signup.headline": "Registrer deg",
24 "signup.firstname.label": "Fornavn",
25 "signup.lastname.label": "Etternavn",
26 "signup.email.label": "Email adresse",
27 "signup.company.label": "Firma",
28 "signup.password.label": "Passord",
29 "signup.submit.label": "Opprett konto",
30 "signup.link.login": "Har du allerede en konto? Logg inn",
31 "signup.emailDuplicate": "En konto med den epost adresse eksiterer allerede",
32 "signup.legal.info": "Ved å opprette en Franz konto aksepterer du",
33 "signup.legal.terms": "Vilkår for bruk",
34 "signup.legal.privacy": "Personvern",
35 "pricing.headline": "Støtt Franz",
36 "pricing.support.label": "Velg din støtteplan",
37 "pricing.submit.label": "Jeg vil støtte utviklingen av Franz",
38 "pricing.link.skipPayment": "Jeg vil ikke støtte utviklingen av Franz.",
39 "import.headline": "Importer dine Franz 4 tjenester",
40 "import.notSupportedHeadline": "Tjenester ikke enda støttet i Franz 5",
41 "import.submit.label": "Importer tjenester",
42 "import.skip.label": "Jeg vil legge til en tjeneste manuelt",
43 "invite.submit.label": "Send invitasjoner",
44 "invite.headline.friends": "Inviter 3 av dine venner eller kolleger",
45 "invite.name.label": "Navn",
46 "invite.email.label": "Email adresse",
47 "invite.skip.label": "Jeg vil gjøre dette senere",
48 "subscription.submit.label": "Jeg vil ikke støtte utviklingen av Franz",
49 "subscription.paymentSessionError": "Kunne ikke laste betalingsskjemaet",
50 "subscription.includedFeatures": "Betalte Franz Premium konto inkluderer",
51 "subscription.features.onpremise": "Legg til on-premise/hosted tjenester som HipChat",
52 "subscription.features.customServices": "Private tjenester for deg og ditt lag",
53 "subscription.features.encryptedSync": "Kryptert øktsynkronisering",
54 "subscription.features.vpn": "Proxy & VPN støtte",
55 "subscription.features.ads": "Ingen annonser, noensinne!",
56 "subscription.features.comingSoon": "Kommer snart",
57 "infobar.servicesUpdated": "Dine tjenester er oppdatert.",
58 "infobar.updateAvailable": "En ny oppdatering for Franz er tilgjengelig.",
59 "infobar.buttonReloadServices": "Oppdater tjenester",
60 "infobar.buttonInstallUpdate": "Restart & installer oppdatering",
61 "infobar.requiredRequestsFailed": "Kunne ikke laste tjenester og brukerinformasjon",
62 "sidebar.settings": "Innstillinger",
63 "sidebar.addNewService": "Legg til ny tjeneste",
64 "services.welcome": "Velkommen til Franz",
65 "services.getStarted": "Kom i gang",
66 "settings.account.headline": "Konto",
67 "settings.account.headlineSubscription": "Ditt abonnement",
68 "settings.account.headlineUpgrade": "Oppgrader din konto og støtt Franz",
69 "settings.account.headlineInvoices": "Fakturaer",
70 "settings.account.manageSubscription.label": "Administrer dine abonnement",
71 "settings.account.accountType.basic": "Enkel Konto",
72 "settings.account.accountType.premium": "Premium Konto",
73 "settings.account.account.editButton": "Rediger konto",
74 "settings.account.invoiceDownload": "Last ned",
75 "settings.account.userInfoRequestFailed": "Kunne ikke laste brukerinformasjon",
76 "settings.account.tryReloadUserInfoRequest": "Prøv igjen",
77 "settings.account.headlineProfile": "Oppdater profil",
78 "settings.account.headlineAccount": "Kontoinformasjon",
79 "settings.account.headlinePassword": "Endre passord",
80 "settings.account.successInfo": "Dine endringer er lagret",
81 "settings.account.buttonSave": "Oppdater profil",
82 "settings.account.mining.thankyou": "Takk for at du støtter Franz med din prosessorkraft.",
83 "settings.account.mining.active": "Du utfører nå {hashes} beregninger per sekund.",
84 "settings.account.mining.moreInformation": "Få mer informasjon",
85 "settings.account.mining.cancel": "Avbryt mining",
86 "settings.navigation.availableServices": "Tilgjengelige tjenester",
87 "settings.navigation.yourServices": "Dine tjenester",
88 "settings.navigation.account": "Konto",
89 "settings.navigation.settings": "Innstillinger",
90 "settings.navigation.logout": "Logg ut",
91 "settings.recipes.headline": "Tilgjengelige tjenester",
92 "settings.recipes.mostPopular": "Mest populære",
93 "settings.recipes.all": "Alle tjenester",
94 "settings.recipes.dev": "Utvikling",
95 "settings.recipes.nothingFound": "Beklager, men ingen tjeneste samsvarer med søkeordet ditt.",
96 "settings.recipes.servicesSuccessfulAddedInfo": "Tjenesten ble lagt til",
97 "settings.service.form.saveButton": "Lagre tjeneste",
98 "settings.service.form.deleteButton": "Slett tjeneste",
99 "settings.service.form.availableServices": "Tilgjengelige tjenester",
100 "settings.service.form.yourServices": "Dine tjenester",
101 "settings.service.form.addServiceHeadline": "Legg til {name}",
102 "settings.service.form.editServiceHeadline": "Rediger {name}",
103 "settings.service.form.tabHosted": "Hosted",
104 "settings.service.form.tabOnPremise": "Selv hosted ⭐️",
105 "settings.service.form.customUrlValidationError": "Kunne ikke validere egendefinert {name} server.",
106 "settings.service.form.customUrlPremiumInfo": "For å legge til selvhost-baserte tjenester trenger du en Franz Premium konto.",
107 "settings.service.form.customUrlUpgradeAccount": "Oppgrader din konto",
108 "settings.service.form.indirectMessageInfo": "Du vil bli varslet om alle nye meldinger i en kanal, ikke bare @brukernavn, @kanal, @here, ...",
109 "settings.service.error.headline": "Error",
110 "settings.service.error.goBack": "Tilbake til tjenester",
111 "settings.service.error.message": "Kunne ikke laste tjeneste oppskrift.",
112 "settings.services.tooltip.isDisabled": "Tjenesten er deaktivert",
113 "settings.services.tooltip.notificationsDisabled": "Varsler er deaktivert",
114 "settings.services.headline": "Dine tjenester",
115 "settings.services.noServicesAdded": "Du har ikke lagt til noen tjenester enda.",
116 "settings.services.discoverServices": "Oppdag tjenester",
117 "settings.services.updatedInfo": "Dine endringer er lagret",
118 "settings.services.deletedInfo": "Tjenester har blitt slettet",
119 "settings.app.headline": "Innstillinger",
120 "settings.app.headlineGeneral": "Genelert",
121 "settings.app.headlineLanguage": "Språk",
122 "settings.app.headlineUpdates": "Oppdateringer",
123 "settings.app.buttonSearchForUpdate": "Se etter oppdateringer",
124 "settings.app.buttonInstallUpdate": "Restart & installer oppdatering",
125 "settings.app.updateStatusSearching": "Søker etter en oppdatering",
126 "settings.app.updateStatusAvailable": "Oppdatering tilgjengelig, laster ned...",
127 "settings.app.updateStatusUpToDate": "Du bruker siste versjon av Franz",
128 "settings.app.form.autoLaunchOnStart": "Start Franz ved oppstart",
129 "settings.app.form.autoLaunchInBackground": "Åpne i bakgrunnen",
130 "settings.app.form.enableSystemTray": "Vis Franz i systemfeltet",
131 "settings.app.form.minimizeToSystemTray": "Minimer Franz til systemfeltet",
132 "settings.app.form.runInBackground": "Behold Franz i bakgrunnen når du lukker vinduet",
133 "settings.app.form.language": "Språk",
134 "settings.app.form.beta": "Inkluder beta versjoner",
135 "settings.app.currentVersion": "Gjeldende versjon:",
136 "settings.service.form.name": "Navn",
137 "settings.service.form.enableService": "Slå på tjeneste",
138 "settings.service.form.enableNotification": "Slå på varsler",
139 "settings.service.form.team": "Lag",
140 "settings.service.form.customUrl": "Egendefinert server",
141 "settings.service.form.indirectMessages": "Vis merke for alle nye meldinger",
142 "settings.user.form.firstname": "Fornavn",
143 "settings.user.form.lastname": "Etternavn",
144 "settings.user.form.email": "Email",
145 "settings.user.form.currentPassword": "Gjeldende passord",
146 "settings.user.form.newPassword": "Nytt passord",
147 "settings.user.form.accountType.label": "Konto type",
148 "settings.user.form.accountType.individual": "Individuell",
149 "settings.user.form.accountType.non-profit": "Non-Profit",
150 "settings.user.form.accountType.company": "Firma",
151 "subscription.type.free": "gratis",
152 "subscription.type.month": "måned",
153 "subscription.type.year": "år",
154 "subscription.type.mining": "Støtt Franz med prosessorkraft",
155 "subscription.mining.headline": "Hvordan fungerer dette?",
156 "subscription.mining.experimental": "eksperimental",
157 "subscription.mining.line1": "Ved å aktivere \"Støtt Franz med prosessorkraft\" vil Franz bruke cirka 20-50% av prosessore din til å mine kryptovalutaen Monero, som vil tilsvare omtrent $5/år",
158 "subscription.mining.line2": "Vi vil tilpasse prosessor bruken basert på arbeidsadferd for å ikke tømme batteriet og senke hastigheten på maskinen din.",
159 "subscription.mining.line3": "Så lenge du miner, har du ubegrenset tilgang til alle Franz Premium funksjoner.",
160 "subscription.mining.moreInformation": "Få mer informasjon om denne planen.",
161 "subscriptionPopup.buttonCancel": "Kanseller",
162 "subscriptionPopup.buttonDone": "Ferdig",
163 "tabs.item.reload": "Reload",
164 "tabs.item.edit": "Rediger",
165 "tabs.item.disableNotifications": "Deaktiver varsler",
166 "tabs.item.enableNotification": "Aktiver varsler",
167 "tabs.item.disableService": "Deaktiver tjeneste",
168 "tabs.item.deleteService": "Slett tjeneste"
169}
diff --git a/src/lib/Menu.js b/src/lib/Menu.js
index a6cde4d36..6bbf302ca 100644
--- a/src/lib/Menu.js
+++ b/src/lib/Menu.js
@@ -1,9 +1,9 @@
1import { remote, shell } from 'electron'; 1import { remote, shell } from 'electron';
2import { autorun, computed, observable, toJS } from 'mobx'; 2import { autorun, computed, observable, toJS } from 'mobx';
3 3
4import { isDevMode, isMac } from '../environment'; 4import { isMac, isLinux } from '../environment';
5 5
6const { app, Menu } = remote; 6const { app, Menu, dialog } = remote;
7 7
8const template = [ 8const template = [
9 { 9 {
@@ -84,6 +84,28 @@ const template = [
84 label: 'Learn More', 84 label: 'Learn More',
85 click() { shell.openExternal('http://meetfranz.com'); }, 85 click() { shell.openExternal('http://meetfranz.com'); },
86 }, 86 },
87 {
88 label: 'Changelog',
89 click() { shell.openExternal('https://github.com/meetfranz/franz/blob/master/CHANGELOG.md'); },
90 },
91 {
92 type: 'separator',
93 },
94 {
95 label: 'Support',
96 click() { shell.openExternal('http://meetfranz.com/support'); },
97 },
98 {
99 type: 'separator',
100 },
101 {
102 label: 'Terms of Service',
103 click() { shell.openExternal('https://meetfranz.com/terms'); },
104 },
105 {
106 label: 'Privacy Statement',
107 click() { shell.openExternal('https://meetfranz.com/privacy'); },
108 },
87 ], 109 ],
88 }, 110 },
89]; 111];
@@ -101,17 +123,15 @@ export default class FranzMenu {
101 _build() { 123 _build() {
102 const tpl = toJS(this.tpl); 124 const tpl = toJS(this.tpl);
103 125
104 if (isDevMode) { 126 tpl[1].submenu.push({
105 tpl[1].submenu.push({ 127 role: 'toggledevtools',
106 role: 'toggledevtools', 128 }, {
107 }, { 129 label: 'Toggle Service Developer Tools',
108 label: 'Toggle Service Developer Tools', 130 accelerator: 'CmdOrCtrl+Shift+Alt+i',
109 accelerator: 'CmdOrCtrl+Shift+Alt+i', 131 click: () => {
110 click: () => { 132 this.actions.service.openDevToolsForActiveService();
111 this.actions.service.openDevToolsForActiveService(); 133 },
112 }, 134 });
113 });
114 }
115 135
116 tpl[1].submenu.unshift({ 136 tpl[1].submenu.unshift({
117 label: 'Reload Service', 137 label: 'Reload Service',
@@ -218,6 +238,18 @@ export default class FranzMenu {
218 role: 'front', 238 role: 'front',
219 }, 239 },
220 ]; 240 ];
241 } else {
242 tpl[4].submenu.unshift({
243 role: 'about',
244 click: () => {
245 dialog.showMessageBox({
246 type: 'info',
247 title: 'Franz',
248 message: 'Franz',
249 detail: `Version: ${remote.app.getVersion()}\nRelease: ${process.versions.electron} / ${process.platform} / ${process.arch}`,
250 });
251 },
252 });
221 } 253 }
222 254
223 const serviceTpl = this.serviceTpl; 255 const serviceTpl = this.serviceTpl;
@@ -244,9 +276,10 @@ export default class FranzMenu {
244 const services = this.stores.services.enabled; 276 const services = this.stores.services.enabled;
245 277
246 if (this.stores.user.isLoggedIn) { 278 if (this.stores.user.isLoggedIn) {
279 const systemAcceleratorKey = isLinux ? 'Alt' : 'CmdOrCtrl';
247 return services.map((service, i) => ({ 280 return services.map((service, i) => ({
248 label: service.name, 281 label: service.name,
249 accelerator: i <= 9 ? `CmdOrCtrl+${i + 1}` : null, 282 accelerator: i <= 9 ? `${systemAcceleratorKey}+${i + 1}` : null,
250 type: 'radio', 283 type: 'radio',
251 checked: service.isActive, 284 checked: service.isActive,
252 click: () => { 285 click: () => {
diff --git a/src/lib/Tray.js b/src/lib/Tray.js
index 525ce592e..2efe71a71 100644
--- a/src/lib/Tray.js
+++ b/src/lib/Tray.js
@@ -7,6 +7,8 @@ const INDICATOR_TRAY_UNREAD = 'tray-unread';
7 7
8export default class TrayIcon { 8export default class TrayIcon {
9 trayIcon = null; 9 trayIcon = null;
10 indicator = 0;
11 themeChangeSubscriberId = null;
10 12
11 show() { 13 show() {
12 if (this.trayIcon) return; 14 if (this.trayIcon) return;
@@ -32,28 +34,43 @@ export default class TrayIcon {
32 this.trayIcon.on('click', () => { 34 this.trayIcon.on('click', () => {
33 app.mainWindow.show(); 35 app.mainWindow.show();
34 }); 36 });
37
38 if (process.platform === 'darwin') {
39 this.themeChangeSubscriberId = systemPreferences.subscribeNotification('AppleInterfaceThemeChangedNotification', () => {
40 this._refreshIcon();
41 });
42 }
35 } 43 }
36 44
37 hide() { 45 hide() {
38 if (this.trayIcon) { 46 if (!this.trayIcon) return;
39 this.trayIcon.destroy(); 47
40 this.trayIcon = null; 48 this.trayIcon.destroy();
49 this.trayIcon = null;
50
51 if (process.platform === 'darwin' && this.themeChangeSubscriberId) {
52 systemPreferences.unsubscribeNotification(this.themeChangeSubscriberId);
53 this.themeChangeSubscriberId = null;
41 } 54 }
42 } 55 }
43 56
44 setIndicator(indicator) { 57 setIndicator(indicator) {
58 this.indicator = indicator;
59 this._refreshIcon();
60 }
61
62 _refreshIcon() {
45 if (!this.trayIcon) return; 63 if (!this.trayIcon) return;
46 64
47 this.trayIcon.setImage(this._getAsset('tray', indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN)); 65 this.trayIcon.setImage(this._getAsset('tray', this.indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN));
48 66
49 if (process.platform === 'darwin') { 67 if (process.platform === 'darwin') {
50 this.trayIcon.setPressedImage( 68 this.trayIcon.setPressedImage(
51 this._getAsset('tray', `${indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN}-active`), 69 this._getAsset('tray', `${this.indicator !== 0 ? INDICATOR_TRAY_UNREAD : INDICATOR_TRAY_PLAIN}-active`),
52 ); 70 );
53 } 71 }
54 } 72 }
55 73
56
57 _getAsset(type, asset) { 74 _getAsset(type, asset) {
58 let platform = process.platform; 75 let platform = process.platform;
59 76
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js
index 7dbef985d..f608a689e 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.js
@@ -13,7 +13,7 @@ import locales from '../i18n/translations';
13import { gaEvent } from '../lib/analytics'; 13import { gaEvent } from '../lib/analytics';
14import Miner from '../lib/Miner'; 14import Miner from '../lib/Miner';
15 15
16const { app, getCurrentWindow, powerMonitor } = remote; 16const { app, powerMonitor } = remote;
17const defaultLocale = 'en-US'; 17const defaultLocale = 'en-US';
18 18
19export default class AppStore extends Store { 19export default class AppStore extends Store {
@@ -112,24 +112,15 @@ export default class AppStore extends Store {
112 setTimeout(window.location.reload, 5000); 112 setTimeout(window.location.reload, 5000);
113 }); 113 });
114 114
115 // Open Dev Tools (even in production mode)
116 key('⌘+ctrl+shift+alt+i, ctrl+shift+alt+i', () => {
117 getCurrentWindow().toggleDevTools();
118 });
119
120 key('⌘+ctrl+shift+alt+pageup, ctrl+shift+alt+pageup', () => {
121 this.actions.service.openDevToolsForActiveService();
122 });
123
124 // Set active the next service 115 // Set active the next service
125 key( 116 key(
126 '⌘+pagedown, ctrl+pagedown, ⌘+shift+tab, ctrl+shift+tab', () => { 117 '⌘+pagedown, ctrl+pagedown, ⌘+tab, ctrl+tab', () => {
127 this.actions.service.setActiveNext(); 118 this.actions.service.setActiveNext();
128 }); 119 });
129 120
130 // Set active the prev service 121 // Set active the prev service
131 key( 122 key(
132 '⌘+pageup, ctrl+pageup, ⌘+tab, ctrl+tab', () => { 123 '⌘+pageup, ctrl+pageup, ⌘+shift+tab, ctrl+shift+tab', () => {
133 this.actions.service.setActivePrev(); 124 this.actions.service.setActivePrev();
134 }); 125 });
135 126
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index 7e797ce55..2ddeeffd4 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -41,6 +41,7 @@ export default class ServicesStore extends Store {
41 this.actions.service.openWindow.listen(this._openWindow.bind(this)); 41 this.actions.service.openWindow.listen(this._openWindow.bind(this));
42 this.actions.service.filter.listen(this._filter.bind(this)); 42 this.actions.service.filter.listen(this._filter.bind(this));
43 this.actions.service.resetFilter.listen(this._resetFilter.bind(this)); 43 this.actions.service.resetFilter.listen(this._resetFilter.bind(this));
44 this.actions.service.resetStatus.listen(this._resetStatus.bind(this));
44 this.actions.service.reload.listen(this._reload.bind(this)); 45 this.actions.service.reload.listen(this._reload.bind(this));
45 this.actions.service.reloadActive.listen(this._reloadActive.bind(this)); 46 this.actions.service.reloadActive.listen(this._reloadActive.bind(this));
46 this.actions.service.reloadAll.listen(this._reloadAll.bind(this)); 47 this.actions.service.reloadAll.listen(this._reloadAll.bind(this));
@@ -341,6 +342,10 @@ export default class ServicesStore extends Store {
341 this.filterNeedle = null; 342 this.filterNeedle = null;
342 } 343 }
343 344
345 @action _resetStatus() {
346 this.actionStatus = [];
347 }
348
344 @action _reload({ serviceId }) { 349 @action _reload({ serviceId }) {
345 const service = this.one(serviceId); 350 const service = this.one(serviceId);
346 service.resetMessageCount(); 351 service.resetMessageCount();