Skip to content

Commit 2c06e4b

Browse files
committed
Add tr/en language support
1 parent 479d490 commit 2c06e4b

File tree

14 files changed

+299
-57
lines changed

14 files changed

+299
-57
lines changed

src/components/AppSidebar.vue

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { useStore } from '../stores/store'
77
import { AppStorage } from '../storage'
88
import { useKey } from '../composables/useKey'
99
import { Page, useRoute } from '../stores/route'
10+
import { useI18n } from '../composables/useI18n'
1011
import { Icons } from './Icons'
1112
import SidebarButton from './SidebarButton.vue'
1213
import Popover from './Popover.vue'
@@ -17,6 +18,7 @@ import PopoverContentInstallUpdate from './PopoverContentInstallUpdate.vue'
1718
1819
const store = useStore()
1920
const route = useRoute()
21+
const { t } = useI18n()
2022
2123
function openCurrentReleaseChangelog() {
2224
open(`${REPO_LINK}/blob/main/CHANGELOG.md#${__APP_VERSION__.replace(/\./g, '')}`)
@@ -25,22 +27,22 @@ function openCurrentReleaseChangelog() {
2527
const moreItems = computed(() => [
2628
menuItem({
2729
key: 'changelog',
28-
meta: { text: 'Changelog', icon: Icons.Info16 },
30+
meta: { text: t.changelog, icon: Icons.Info16 },
2931
onSelect: openCurrentReleaseChangelog,
3032
}),
3133
menuItem({
3234
key: 'settings',
33-
meta: { text: 'Settings', icon: Icons.Gear16 },
35+
meta: { text: t.settings, icon: Icons.Gear16 },
3436
onSelect: () => route.go(Page.Settings),
3537
}),
3638
AppStorage.get('user') != null && menuItem({
3739
key: 'logout',
38-
meta: { text: 'Log out', icon: Icons.SignOut16 },
40+
meta: { text: t.logOut, icon: Icons.SignOut16 },
3941
onSelect: store.logout,
4042
}),
4143
menuItem({
4244
key: 'exit',
43-
meta: { text: 'Exit app', icon: Icons.X },
45+
meta: { text: t.exitApp, icon: Icons.X },
4446
onSelect: () => exit(0),
4547
}),
4648
])
@@ -70,7 +72,7 @@ useKey('r', () => {
7072
<Tooltip
7173
:target="el"
7274
position="right"
73-
text="Navigate to repository"
75+
:text="t.navigateToRepository"
7476
/>
7577
</template>
7678
</SlotRef>
@@ -88,7 +90,7 @@ useKey('r', () => {
8890
<Tooltip
8991
:target="el"
9092
position="right"
91-
text="A new version is available"
93+
:text="t.aNewVersionIsAvailable"
9294
/>
9395

9496
<Popover
@@ -118,7 +120,7 @@ useKey('r', () => {
118120
<Tooltip
119121
:target="el"
120122
position="right"
121-
text="Reload notifications (R)"
123+
:text="t.reloadNotifications('R')"
122124
/>
123125
</template>
124126
</SlotRef>
@@ -134,7 +136,7 @@ useKey('r', () => {
134136
<Tooltip
135137
position="right"
136138
:target="el"
137-
text="More"
139+
:text="t.more"
138140
/>
139141

140142
<Popover

src/components/NotificationItem.vue

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<script lang="ts" setup>
2-
import dayjs from 'dayjs'
32
import type { MinimalRepository, Thread } from '../api/notifications'
43
import type { NotificationList } from '../types'
5-
import { formatReason, isRepository, isThread, notificationSubjectIcon } from '../utils/notification'
4+
import { isRepository, isThread, notificationSubjectIcon } from '../utils/notification'
5+
import { useI18n } from '../composables/useI18n'
6+
import { fromNow } from '../utils/date'
67
import Separator from './Separator.vue'
78
89
interface Props {
@@ -25,6 +26,7 @@ const props = withDefaults(defineProps<Props>(), {
2526
checkable: false,
2627
})
2728
const emit = defineEmits<Emits>()
29+
const { t } = useI18n()
2830
2931
function isInteractedCheckbox(e: MouseEvent | KeyboardEvent) {
3032
return e.target instanceof HTMLElement && e.target.closest('.notification-checkbox') != null
@@ -121,9 +123,9 @@ function handleRepoClick(repo: MinimalRepository, event: MouseEvent | KeyboardEv
121123
</div>
122124

123125
<div class="notification-item-content-subtitle">
124-
{{ formatReason(value.reason) }}
126+
{{ t.reason[value.reason] }}
125127
-
126-
{{ dayjs(value.updated_at).fromNow() }}
128+
{{ fromNow(value.updated_at) }}
127129
</div>
128130
</div>
129131

src/components/PopoverContentInstallUpdate.vue

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script lang="ts" setup>
22
import type { UpdateManifest } from '@tauri-apps/api/updater'
3+
import { useI18n } from '../composables/useI18n'
34
import AppButton from './AppButton.vue'
45
import EmptyState from './EmptyState.vue'
56
@@ -9,15 +10,15 @@ interface Props {
910
}
1011
1112
defineProps<Props>()
12-
1313
defineEmits<{ (e: 'install'): void }>()
1414
15+
const { t } = useI18n()
1516
const appVersion = __APP_VERSION__
1617
</script>
1718

1819
<template>
1920
<div class="install-update">
20-
<EmptyState :description="`Gitification ${manifest.version} is available!`">
21+
<EmptyState :description="t.gitificationVersionIsAvailable(manifest.version)">
2122
<template #icon>
2223
<img
2324
style="border-radius: 50%;"
@@ -30,14 +31,14 @@ const appVersion = __APP_VERSION__
3031

3132
<template #footer>
3233
<p class="pharagraph">
33-
Current version is <b>{{ appVersion }}</b>
34+
<component :is="t.currentVersionIs(appVersion)" />
3435
</p>
3536

3637
<AppButton
3738
:loading="loading"
3839
@click="$emit('install')"
3940
>
40-
Install
41+
{{ t.install }}
4142
</AppButton>
4243
</template>
4344
</EmptyState>

src/composables/useI18n.ts

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
import { createSharedComposable, reactiveComputed } from '@vueuse/core'
2+
import { Fragment, customRef, h, ref } from 'vue'
3+
import { AppStorage } from '../storage'
4+
import { type NotificationReason } from '../constants'
5+
6+
export type Locale = 'en' | 'tr'
7+
8+
const en = {
9+
navigateToRepository: 'Navigate to repository',
10+
reloadNotifications: (shortcut: string) => `Reload notifications (${shortcut})`,
11+
more: 'More',
12+
changelog: 'Changelog',
13+
aNewVersionIsAvailable: 'A new version is available!',
14+
settings: 'Settings',
15+
signOut: 'Sign out',
16+
logOut: 'Log out',
17+
exitApp: 'Exit app',
18+
itsAllClear: 'It\'s all clear sir!',
19+
appearance: 'Appearance',
20+
theme: 'Theme',
21+
system: 'System',
22+
light: 'Light',
23+
dark: 'Dark',
24+
systemTitle: 'System',
25+
sounds: 'Sounds',
26+
openAtStartup: 'Open at startup',
27+
showSystemNotifications: 'Show system notifications',
28+
notificationsTitle: 'Notifications',
29+
showOnlyParticipating: 'Show only participating',
30+
showReadNotifications: 'Show read notifications',
31+
markAsReadOnOpen: 'Mark as read on open',
32+
markAsReadOpenDescription: 'When you open some notifications, Github marks them as read automaticlly, but for some it doesn\'t.',
33+
welcomeToGitification: 'Welcome to Gitification',
34+
loginViaGithub: 'Login via Github',
35+
oopsieCouldntLoad: 'Oopsie! Couldn\'t load notifications',
36+
refresh: 'Refresh',
37+
clearSelections: 'Clear selections',
38+
unsubscribe: 'Unsubscribe',
39+
open: 'Open',
40+
markAsRead: 'Mark as read',
41+
unsubscribeAll: 'Unsubscribe all',
42+
openAll: 'Open all',
43+
markAllAsRead: 'Mark all as read',
44+
selectAll: 'Select all',
45+
unselectAll: 'Unselect all',
46+
select: 'Select',
47+
unselect: 'Unselect',
48+
gitificationVersionIsAvailable: (version: string) => `Gitification ${version} is available!`,
49+
currentVersionIs: (version: string) => () => h(Fragment, null, [
50+
'Current version is ',
51+
h('b', null, version),
52+
]),
53+
install: 'Install',
54+
reason: {
55+
assign: 'Assign',
56+
author: 'Author',
57+
comment: 'Comment',
58+
invitation: 'Invitation',
59+
manual: 'Manual',
60+
mention: 'Mention',
61+
review_requested: 'Review requested',
62+
security_alert: 'Security alert',
63+
state_change: 'State change',
64+
subscribed: 'Subscribed',
65+
team_mention: 'Team mention',
66+
ci_activity: 'CI activity',
67+
} satisfies Record<NotificationReason, string>,
68+
goBack: (shortcut: string) => `Go back (${shortcut})`,
69+
language: {
70+
title: 'Language',
71+
en: 'English',
72+
tr: 'Türkçe',
73+
},
74+
}
75+
76+
const tr: typeof en = {
77+
navigateToRepository: 'Repoya git',
78+
reloadNotifications: (shortcut: string) => `Bildirimleri yenile (${shortcut})`,
79+
more: 'Daha fazla',
80+
changelog: 'Yenilikler',
81+
aNewVersionIsAvailable: 'Yeni bir sürüm mevcut!',
82+
settings: 'Ayarlar',
83+
signOut: 'Çıkış yap',
84+
logOut: 'Çıkış yap',
85+
exitApp: 'Uygulamadan Çık',
86+
itsAllClear: 'Hepsi okundu!',
87+
appearance: 'Görünüm',
88+
theme: 'Tema',
89+
system: 'Sistem',
90+
light: 'Açık',
91+
dark: 'Koyu',
92+
systemTitle: 'Sistem',
93+
sounds: 'Sesler',
94+
openAtStartup: 'Başlangıçta aç',
95+
showSystemNotifications: 'Sistem bildirimleri göster',
96+
notificationsTitle: 'Bildirimler',
97+
showOnlyParticipating: 'Sadece dahil olduklarımı göster',
98+
showReadNotifications: 'Okunmuş bildirimleri göster',
99+
markAsReadOnOpen: 'Açınca okundu olarak işaretle',
100+
markAsReadOpenDescription: 'Bazı bildirimleri açınca Github otomatik olarak okundu olarak işaretliyor ama bazılarını işaretlemiyor. Bu ayar ile her zaman okundu olarak işaretleyebilirsin.',
101+
welcomeToGitification: 'Gitification\'a hoşgeldin',
102+
loginViaGithub: 'Github ile giriş yap',
103+
oopsieCouldntLoad: 'Tüh be! Bildirimler yüklenemedi',
104+
refresh: 'Yenile',
105+
clearSelections: 'Seçimleri temizle',
106+
unsubscribe: 'Aboneliği kaldır',
107+
open: 'Aç',
108+
markAsRead: 'Okundu olarak işaretle',
109+
unsubscribeAll: 'Tümünün aboneliğini kaldır',
110+
openAll: 'Tümünü aç',
111+
markAllAsRead: 'Tümünü okundu olarak işaretle',
112+
selectAll: 'Tümünü seç',
113+
unselectAll: 'Tüm seçimi kaldır',
114+
select: 'Seç',
115+
unselect: 'Seçimi kaldır',
116+
gitificationVersionIsAvailable: (version: string) => `Gitification ${version} yayında!`,
117+
currentVersionIs: (version: string) => () => h(Fragment, null, [
118+
'Şuanki versiyon ',
119+
h('b', null, version),
120+
]),
121+
install: 'Yükle',
122+
reason: {
123+
assign: 'Atama',
124+
author: 'Yazar',
125+
comment: 'Yorum',
126+
invitation: 'Davet',
127+
manual: 'Manuel',
128+
mention: 'Bahsetme',
129+
review_requested: 'İnceleme İstendi',
130+
security_alert: 'Güvenlik Uyarısı',
131+
state_change: 'Durum Değişimi',
132+
subscribed: 'Abone Olundu',
133+
team_mention: 'Takım bahsetmesi',
134+
ci_activity: 'CI etkinliği',
135+
} satisfies Record<NotificationReason, string>,
136+
goBack: (shortcut: string) => `Geri (${shortcut})`,
137+
language: {
138+
title: 'Dil',
139+
en: 'English',
140+
tr: 'Türkçe',
141+
},
142+
}
143+
144+
const localeMap: Record<Locale, typeof en> = { en, tr }
145+
146+
export const useI18n = createSharedComposable(() => {
147+
const currentLanguage = customRef<Locale>((track, trigger) => {
148+
const locale = ref<Locale>('tr')
149+
150+
return {
151+
get() {
152+
track()
153+
return locale.value
154+
},
155+
set(value) {
156+
locale.value = value
157+
AppStorage.set('language', value)
158+
trigger()
159+
},
160+
}
161+
})
162+
163+
const t = reactiveComputed(() => localeMap[currentLanguage.value])
164+
165+
return {
166+
currentLanguage,
167+
t,
168+
}
169+
})

src/constants.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ export const reasonFormatMap = {
7878
[NotificationReason.Subscribed]: 'Subscribed',
7979
[NotificationReason.TeamMention]: 'Team Mention',
8080
[NotificationReason.CiActivity]: 'CI Activity',
81-
8281
}
8382

8483
export const subjectIconMap = {

src/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import { useStore } from './stores/store'
1717
import { initDevtools } from './utils/initDevtools'
1818
import { useKey } from './composables/useKey'
1919
import { Page, useRoute } from './stores/route'
20+
import 'dayjs/locale/en'
21+
import 'dayjs/locale/tr'
2022

2123
async function main() {
2224
if (import.meta.env.DEV) {

0 commit comments

Comments
 (0)