Skip to content

Commit

Permalink
feat(web): add support for localization
Browse files Browse the repository at this point in the history
closes: #267

Signed-off-by: Jordan Shatford <[email protected]>
  • Loading branch information
jordanshatford committed Nov 25, 2024
1 parent f01ed6a commit 4489bf1
Show file tree
Hide file tree
Showing 27 changed files with 1,125 additions and 180 deletions.
5 changes: 5 additions & 0 deletions .changeset/hip-walls-cough.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cq/web": minor
---

feat: add support for localization
3 changes: 2 additions & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"recommendations": [
"vue.volar",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode"
"esbenp.prettier-vscode",
"inlang.vs-code-extension"
]
}
1 change: 1 addition & 0 deletions apps/web/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/paraglide
7 changes: 6 additions & 1 deletion apps/web/eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import vue from '@cq/config/eslint/vue'

/** @type {import('eslint').Linter.Config[]} */
export default vue
export default [
{
ignores: ['src/paraglide/*']
},
...vue
]
96 changes: 96 additions & 0 deletions apps/web/messages/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
{
"$schema": "https://inlang.com/schema/inlang-message-format",
"allowed_commands": "Allowed Commands:",
"allowed_commands_description": "Commands allowed to be used in chat.",
"allowed_providers": "Allowed Providers:",
"allowed_providers_description": "Clips from these providers will be allowed in the queue.",
"application_version": "Application version: v{version}",
"auto_mod": "Auto Moderation:",
"auto_mod_description": "When a user has their chat message deleted, is timed out, or banned, the clips they submitted will be removed.",
"cancel": "Cancel",
"chat_settings_saved": "Chat settings saved.",
"clear": "Clear",
"clips": "{length} clip(s)",
"clip_cache_purged": "Clip cache purged.",
"clip_history_purged": "Clip history purged.",
"close": "Close",
"confirm": "Confirm",
"command_prefix": "Command Prefix:",
"command_prefix_description": "Commands in chat must be prefixed by this value.",
"command_open": "Open the queue.",
"command_close": "Close the queue.",
"command_clear": "Remove all clips in the queue.",
"command_set_limit": "Set queue size limit.",
"command_remove_limit": "Remove the queue size limit.",
"command_previous": "Switch to the previous clip.",
"command_next": "Switch to the next clip.",
"command_remove_by_submitter": "Remove clips sent by the submitter.",
"command_remove_by_provider": "Remove clips from the provider.",
"command_enable_provider": "Enable the specified provider.",
"command_disable_provider": "Disable the specified provider.",
"command_enable_auto_mod": "Enable auto moderation.",
"command_disable_auto_mod": "Disable auto moderation.",
"command_purge_cache": "Purge all cached clips.",
"command_purge_history": "Purge all historically watched clips.",
"connected_chat_colon": "Connected Chat:",
"delete_history": "Delete History",
"delete_history_confirm": "Are you sure you want to delete {length} clip(s) from the history?",
"delete_label": "Delete",
"experimental_providers_selected": "Experimental providers selected: {names}",
"feature_connect_title": "Connect to Chat",
"feature_connect_description": "Log in to automatically connect to your Twitch chat. Clips submitted by users in chat will be queued.",
"feature_duplicate_prevent_title": "Duplicate Prevention",
"feature_duplicate_prevent_description": "Duplicate clips will not make it into the queue. This includes clips watched during previous sessions.",
"feature_popularity_title": "Popular Clips Rise Up",
"feature_popularity_description": "Clips being repeately submitted by many users will rise up in the queue allowing it to be viewed sooner.",
"feature_commands_title": "Chat Commands",
"feature_commands_description": "Moderators of the channel can use chat commands to interact directly with the queue.",
"feature_moderation_title": "Automatic Moderation",
"feature_moderation_description": "Moderation performed in chat will effect the clips submitted by those users.",
"feature_settings_title": "Settings Customization",
"feature_settings_description": "Personalize your experience through the vast choices of customizable settings.",
"history": "History",
"info": "Info",
"message_no_clip_providers_enabled": "No clip providers enabled. Please enable one in the settings.",
"next": "Next",
"none": "None",
"no_clips_previously_watched": "No clips previously watched.",
"open": "Open",
"play": "Play",
"preferences_saved": "Preferences saved.",
"previous": "Previous",
"primary_color": "Primary Color:",
"primary_color_description": "Primary color used throughout the UI.",
"provider": "Provider",
"provider_colon": "Provider:",
"purge_cache": "Purge Cache",
"purge_cache_description": "Clips submitted may be cached for future use. Purge all cached clips.",
"purge_cache_confirm": "Are you sure you want to purge all clips cached locally?",
"purge_history": "Purge History",
"purge_history_description": "Purge all clips previously viewed allowing them to be resubmitted.",
"purge_history_confirm": "Are you sure you want to purge all clips from the history?",
"queue": "Queue",
"queue_settings_saved": "Queue settings saved.",
"remove": "Remove",
"reset_settings": "Reset Settings",
"reset_settings_description": "Reset settings back to their initial values.",
"reset_settings_confirm": "Are you sure you want to reset all settings to the default values?",
"save": "Save",
"search": "Search",
"settings": "Settings",
"settings_chat": "Chat Settings",
"settings_other": "Other Settings",
"settings_preferences": "Preferences",
"settings_queue": "Queue Settings",
"settings_reset": "Settings reset to default.",
"size_limit": "Size Limit:",
"size_limit_description": "The number of clips allowed in the queue. Leave empty for no limit.",
"success": "Success",
"submitter": "Submitter",
"submitter_name": "Submitter: {name}",
"surface_color": "Surface Color:",
"surface_color_description": "Surface color used throughout the UI.",
"tagline": "An enhanced clip viewing experience.",
"title": "Clip Queue",
"upcoming_clips": "Upcoming Clips"
}
4 changes: 3 additions & 1 deletion apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"build": "pnpm typecheck && vite build",
"preview": "vite preview",
"typecheck": "vue-tsc --build --force",
"lint": "prettier --check . && eslint .",
"lint": "prettier --check . && eslint . && pnpx @inlang/cli lint --project ./project.inlang",
"lint:fix": "eslint . --fix",
"format": "prettier --write ."
},
Expand All @@ -26,6 +26,8 @@
},
"devDependencies": {
"@cq/config": "workspace:*",
"@inlang/paraglide-js": "1.11.3",
"@inlang/paraglide-vite": "^1.2.77",
"@pinia/testing": "^0.1.7",
"@tsconfig/node20": "^20.1.4",
"@types/jsdom": "^21.1.7",
Expand Down
1 change: 1 addition & 0 deletions apps/web/project.inlang/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cache
1 change: 1 addition & 0 deletions apps/web/project.inlang/project_id
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
e3ad4c3195c1fe93ba0732d0c48e8836c18c751af29938bdd03543ceadddb43b
18 changes: 18 additions & 0 deletions apps/web/project.inlang/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"$schema": "https://inlang.com/schema/project-settings",
"sourceLanguageTag": "en",
"languageTags": ["en"],
"modules": [
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-empty-pattern@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-missing-translation@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-without-source@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-identical-pattern@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-valid-js-identifier@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-snake-case-id@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@latest/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@latest/dist/index.js"
],
"plugin.inlang.messageFormat": {
"pathPattern": "./messages/{languageTag}.json"
}
}
24 changes: 13 additions & 11 deletions apps/web/src/components/ClipCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,34 @@
<template #title>
<span class="font-normal">{{ clip.title }}</span>
</template>
<template #subtitle> </template>
<template #subtitle>
<p v-if="clip.category">{{ clip.channel }} - {{ clip.category }}</p>
<p v-else>
{{ clip.channel }}
</p>
</template>
<template #content>
<div class="mb-4 text-xs text-surface-400">
<p v-if="clip.category">{{ clip.channel }} - {{ clip.category }}</p>
<p v-else>
{{ clip.channel }}
</p>
<p>Submitter: {{ clip.submitters[0] }}</p>
<p>{{ m.submitter_name({ name: clip.submitters[0] }) }}</p>
<div class="flex items-center gap-1">
<p>Provider:</p>
<p>{{ m.provider_colon() }}</p>
<ProviderName :provider="clip.provider" class="font-normal" />
</div>
</div>
<div class="flex justify-around">
<Button
icon="pi pi-play"
title="Play"
label="Play"
:title="m.play()"
:label="m.play()"
severity="info"
size="small"
@click="emit('play')"
>
</Button>
<Button
icon="pi pi-trash"
title="Remove"
label="Remove"
:title="m.remove()"
:label="m.remove()"
severity="danger"
size="small"
@click="emit('remove')"
Expand All @@ -53,6 +54,7 @@ import type { Clip } from '@cq/providers'
import { Button, Card } from '@cq/ui'

import ProviderName from '@/components/ProviderName.vue'
import * as m from '@/paraglide/messages'

export interface Props {
clip: Clip
Expand Down
9 changes: 6 additions & 3 deletions apps/web/src/components/ClipPlayer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<div class="flex gap-2">
<Button
icon="pi pi-backward"
label="Previous"
:label="m.previous()"
severity="info"
size="small"
:disabled="previousDisabled"
Expand All @@ -33,7 +33,7 @@
<Button
icon="pi pi-forward"
icon-pos="right"
label="Next"
:label="m.next()"
severity="info"
size="small"
:disabled="nextDisabled"
Expand All @@ -46,7 +46,9 @@
<span>
{{ clip.channel }}
<span v-if="clip.category"> - {{ clip.category }} </span>
<span v-if="clip.submitters[0]"> - Submitter: {{ clip.submitters[0] }} </span>
<span v-if="clip.submitters[0]">
- {{ m.submitter_name({ name: clip.submitters[0] }) }}</span
>
</span>
<ProviderName :provider="clip.provider" />
</div>
Expand All @@ -61,6 +63,7 @@ import type { Clip, PlayerFormat } from '@cq/providers'
import Player from '@cq/player'
import { Button } from '@cq/ui'

import * as m from '@/paraglide/messages'
import { useProviders } from '@/stores/providers'
import ProviderName from './ProviderName.vue'

Expand Down
7 changes: 4 additions & 3 deletions apps/web/src/components/ClipQueue.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<div class="float-right">
<Button
severity="info"
label="Clear"
:label="m.clear()"
size="small"
:disabled="clips.length === 0"
class="ml-2"
Expand All @@ -13,7 +13,7 @@
</Button>
<Button
:severity="isOpen ? 'danger' : 'info'"
:label="isOpen ? 'Close' : 'Open'"
:label="isOpen ? m.close() : m.open()"
size="small"
class="ml-2"
@click="isOpen ? emit('close') : emit('open')"
Expand All @@ -23,7 +23,7 @@
<div class="text-left">
<p class="text-lg font-normal text-surface-600 dark:text-surface-400">{{ title }}</p>
<span class="mt-3 text-sm font-normal text-surface-400 dark:text-surface-600">
{{ clips.length }} {{ clips.length === 1 ? 'clip' : 'clips' }}
{{ m.clips({ length: clips.length }) }}
</span>
</div>
<div class="mt-3 flex justify-items-start overflow-x-auto">
Expand All @@ -45,6 +45,7 @@ import { toUUID } from '@cq/providers'
import { Button } from '@cq/ui'

import ClipCard from '@/components/ClipCard.vue'
import * as m from '@/paraglide/messages'

export interface Props {
title?: string
Expand Down
35 changes: 16 additions & 19 deletions apps/web/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as m from '@/paraglide/messages'

export const env = {
CLIENT_ID: import.meta.env.VITE_TWITCH_CLIENT_ID as string,
REDIRECT_URI: import.meta.env.VITE_TWITCH_REDIRECT_URI as string,
Expand All @@ -6,42 +8,37 @@ export const env = {

export const config = {
about: {
title: 'Clip Queue',
tagline: 'An enhanced clip viewing experience.',
title: m.title(),
tagline: m.tagline(),
features: [
{
title: 'Connect to Chat',
description:
'Log in to automatically connect to your Twitch chat. Clips submitted by users in chat will be queued.',
title: m.feature_connect_title(),
description: m.feature_connect_description(),
icon: 'pi pi-comments'
},
{
title: 'Duplicate Prevention',
description:
'Duplicate clips will not make it into the queue. This includes clips watched during previous sessions.',
title: m.feature_duplicate_prevent_title(),
description: m.feature_duplicate_prevent_description(),
icon: 'pi pi-copy'
},
{
title: 'Popular Clips Rise Up',
description:
'Clips being repeately submitted by many users will rise up in the queue allowing it to be viewed sooner.',
title: m.feature_popularity_title(),
description: m.feature_popularity_description(),
icon: 'pi pi-chart-line'
},
{
title: 'Chat Commands',
description:
'Moderators of the channel can use chat commands to interact directly with the queue.',
title: m.feature_commands_title(),
description: m.feature_commands_description(),
icon: 'pi pi-bolt'
},
{
title: 'Automatic Moderation',
description: 'Moderation performed in chat will effect the clips submitted by those users.',
title: m.feature_moderation_title(),
description: m.feature_moderation_description(),
icon: 'pi pi-flag'
},
{
title: 'Settings Customization',
description:
'Personalize your experience through the vast choices of customizable settings.',
title: m.feature_settings_title(),
description: m.feature_settings_description(),
icon: 'pi pi-cog'
}
]
Expand Down
Loading

0 comments on commit 4489bf1

Please sign in to comment.