diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 195eb94..b39f2f8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,32 +23,23 @@ jobs: fetch-tags: true token: ${{ secrets.GITHUB_TOKEN }} - - name: Get base tag - id: get_base_tag + - name: Determine final version + id: get_final_ver run: | - git fetch --tags - - TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") - echo "Using base tag: $TAG" - echo "base_tag=$TAG" >> $GITHUB_OUTPUT - - - name: Determine final tag - id: get_final_tag - run: | - BASE_TAG=${{ steps.get_base_tag.outputs.base_tag }} + BASE_VER=v$(jq -r '.version' package.json) TODAY=$(date +'%Y.%m.%d') echo "Today will be: $TODAY" echo "today=$TODAY" >> $GITHUB_OUTPUT if [[ "${{ github.event_name }}" == "release" ]]; then - FINAL_TAG="$BASE_TAG" + FINAL_VER="$BASE_VER" else - FINAL_TAG="${BASE_TAG}-nightly.$TODAY" + FINAL_VER="${BASE_VER}-nightly.$TODAY" fi - echo "Drop's release tag will be: $FINAL_TAG" - echo "final_tag=$FINAL_TAG" >> $GITHUB_OUTPUT + echo "Drop's release tag will be: $FINAL_VER" + echo "final_ver=$FINAL_VER" >> $GITHUB_OUTPUT - name: Set up QEMU uses: docker/setup-qemu-action@v3 @@ -74,7 +65,7 @@ jobs: ghcr.io/drop-OSS/drop tags: | type=schedule,pattern=nightly - type=schedule,pattern=nightly.${{ steps.get_final_tag.outputs.today }} + type=schedule,pattern=nightly.${{ steps.get_final_ver.outputs.today }} type=semver,pattern=v{{version}} type=semver,pattern=v{{major}}.{{minor}} type=semver,pattern=v{{major}} @@ -98,4 +89,4 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max build-args: | - BUILD_DROP_VERSION=${{ steps.get_final_tag.outputs.final_tag }} + BUILD_DROP_VERSION=${{ steps.get_final_ver.outputs.final_ver }} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..2fc7cb9 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,12 @@ +{ + "recommendations": [ + "lokalise.i18n-ally", + "esbenp.prettier-vscode", + "Prisma.prisma", + "bradlc.vscode-tailwindcss", + "Vue.volar", + "arktypeio.arkdark", + "EditorConfig.EditorConfig", + "dbaeumer.vscode-eslint" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index e426a5e..a7c41eb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,5 +17,20 @@ "strings": "on" }, // prioritize ArkType's "type" for autoimports - "typescript.preferences.autoImportSpecifierExcludeRegexes": ["^(node:)?os$"] + "typescript.preferences.autoImportSpecifierExcludeRegexes": ["^(node:)?os$"], + // i18n Ally settings + "i18n-ally.sortKeys": true, + "i18n-ally.keepFulfilled": true, + "i18n-ally.extract.autoDetect": true, + "i18n-ally.localesPaths": ["i18n", "i18n/locales"], + "i18n-ally.keystyle": "nested", + "i18n-ally.extract.ignored": [ + "string >= 14", + "string.alphanumeric >= 5", + "/api/v1/admin/import/version/preload?id=${encodeURIComponent(\n gameId,\n )}&version=${encodeURIComponent(version)}" + ], + "i18n-ally.extract.ignoredByFiles": { + "pages/admin/library/sources/index.vue": ["Filesystem"], + "components/NewsArticleCreateButton.vue": ["[", "`", "Enter"] + } } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3d883ae..1cc3faf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -130,6 +130,10 @@ and [create an issue](#reporting-issues) or [submit a PR](#submitting-pull-reque --- +## Translation + +If you want to help translate Drop, we would love to have your help! You can do so on our weblate instance. Please make sure to read the [message format syntax](https://vue-i18n.intlify.dev/guide/essentials/syntax.html) page before starting. Failure to do so may result in your translations causing errors in Drop. + ## Commit Guidelines Drop uses the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) diff --git a/components/AccountSidebar.vue b/components/AccountSidebar.vue index 927988b..11335fc 100644 --- a/components/AccountSidebar.vue +++ b/components/AccountSidebar.vue @@ -1,7 +1,7 @@ diff --git a/components/Auth/Simple.vue b/components/Auth/Simple.vue index a38fe8d..e2dfebc 100644 --- a/components/Auth/Simple.vue +++ b/components/Auth/Simple.vue @@ -4,7 +4,7 @@ {{ $t("auth.username") }}
Password{{ $t("auth.password") }}
Remember me{{ $t("auth.signin.rememberMe") }}
- Forgot password?{{ $t("auth.signin.forgot") }}
- Sign in + {{ + $t("auth.signin.signin") + }}
@@ -93,6 +97,7 @@ const error = ref(); const route = useRoute(); const router = useRouter(); +const { t } = useI18n(); function signin_wrapper() { loading.value = true; @@ -101,7 +106,7 @@ function signin_wrapper() { router.push(route.query.redirect?.toString() ?? "/"); }) .catch((response) => { - const message = response.statusMessage || "An unknown error occurred"; + const message = response.statusMessage || t("errors.unknown"); error.value = message; }) .finally(() => { diff --git a/components/CreateCollectionModal.vue b/components/CreateCollectionModal.vue index be4e806..62dd59b 100644 --- a/components/CreateCollectionModal.vue +++ b/components/CreateCollectionModal.vue @@ -3,11 +3,10 @@ @@ -60,6 +59,7 @@ const emit = defineEmits<{ const open = defineModel({ required: true }); +const { t } = useI18n(); const collectionName = ref(""); const createCollectionLoading = ref(false); const collections = await useCollections(); @@ -101,8 +101,10 @@ async function createCollection() { createModal( ModalType.Notification, { - title: "Failed to create collection", - description: `Drop couldn't create your collection: ${err?.statusMessage}`, + title: t("errors.library.collection.create.title"), + description: t("errors.library.collection.create.desc", [ + err?.statusMessage ?? t("errors.unknown"), + ]), }, (_, c) => c(), ); diff --git a/components/DeleteCollectionModal.vue b/components/DeleteCollectionModal.vue index 76e842c..d057666 100644 --- a/components/DeleteCollectionModal.vue +++ b/components/DeleteCollectionModal.vue @@ -6,13 +6,13 @@ as="h3" class="text-lg font-bold font-display text-zinc-100" > - Delete Collection + {{ $t("library.collection.delete") }}

- Are you sure you want to delete "{{ collection?.name }}"? + {{ $t("common.deleteConfirm", [collection?.name]) }}

- This action cannot be undone. + {{ $t("common.cannotUndo") }}

@@ -22,13 +22,13 @@ class="bg-red-600 text-white hover:bg-red-500" @click="() => deleteCollection()" > - Delete + {{ $t("delete") }} @@ -42,6 +42,7 @@ const collection = defineModel(); const deleteLoading = ref(false); const collections = await useCollections(); +const { t } = useI18n(); async function deleteCollection() { try { @@ -62,9 +63,11 @@ async function deleteCollection() { createModal( ModalType.Notification, { - title: "Failed to add game to library", - // @ts-expect-error attempt to display statusMessage on error - description: `Drop couldn't add this game to your library: ${e?.statusMessage}`, + title: t("errors.library.add.title"), + description: t("errors.library.add.desc", [ + // @ts-expect-error attempt to display statusMessage on error + e?.statusMessage ?? t("errors.unknown"), + ]), }, (_, c) => c(), ); diff --git a/components/DeleteNewsModal.vue b/components/DeleteNewsModal.vue index 8f508d7..47915fe 100644 --- a/components/DeleteNewsModal.vue +++ b/components/DeleteNewsModal.vue @@ -6,13 +6,13 @@ as="h3" class="text-lg font-bold font-display text-zinc-100" > - Delete Article + {{ $t("news.delete") }}

- Are you sure you want to delete "{{ article?.title }}"? + {{ $t("common.deleteConfirm", [article?.title]) }}

- This action cannot be undone. + {{ $t("common.cannotUndo") }}

@@ -22,13 +22,13 @@ class="bg-red-600 text-white hover:bg-red-500" @click="() => deleteArticle()" > - Delete + {{ $t("delete") }} @@ -45,6 +45,7 @@ interface Article { const article = defineModel
(); const deleteLoading = ref(false); const router = useRouter(); +const { t } = useI18n(); const news = useNews(); if (!news.value) { news.value = await fetchNews(); @@ -68,9 +69,11 @@ async function deleteArticle() { createModal( ModalType.Notification, { - title: "Failed to delete article", - // @ts-expect-error attempt to display statusMessage on error - description: `Drop couldn't delete this article: ${e?.statusMessage}`, + title: t("errors.news.article.delete.title"), + description: t("errors.news.article.delete.desc", [ + // @ts-expect-error attempt to display statusMessage on error + e?.statusMessage ?? t("errors.unknown"), + ]), }, (_, c) => c(), ); diff --git a/components/DropWordmark.vue b/components/DropWordmark.vue index ae9b39b..7288677 100644 --- a/components/DropWordmark.vue +++ b/components/DropWordmark.vue @@ -11,8 +11,8 @@ /> - Drop + + {{ $t("drop.drop") }} + diff --git a/components/EmojiText.vue b/components/EmojiText.vue new file mode 100644 index 0000000..ee90157 --- /dev/null +++ b/components/EmojiText.vue @@ -0,0 +1,17 @@ + + + diff --git a/components/GamePanel.vue b/components/GamePanel.vue index 9aaa9cc..9307ec1 100644 --- a/components/GamePanel.vue +++ b/components/GamePanel.vue @@ -32,7 +32,7 @@

- > + diff --git a/components/SourceOptions/Filesystem.vue b/components/SourceOptions/Filesystem.vue index 9448c06..9f3e310 100644 --- a/components/SourceOptions/Filesystem.vue +++ b/components/SourceOptions/Filesystem.vue @@ -1,10 +1,12 @@ @@ -84,6 +86,8 @@ import { DocumentIcon } from "@heroicons/vue/24/outline"; import type { Article } from "~/prisma/client"; import type { SerializeObject } from "nitropack/types"; +const { t } = useI18n(); + const { articles } = defineProps<{ articles: SerializeObject< Article & { @@ -93,16 +97,8 @@ const { articles } = defineProps<{ >[]; }>(); -const formatDate = (date: string) => { - return new Date(date).toLocaleDateString("en-AU", { - year: "numeric", - month: "long", - day: "numeric", - }); -}; - useHead({ - title: "News", + title: t("userHeader.links.news"), }); diff --git a/pages/store/[id]/index.vue b/pages/store/[id]/index.vue index 844082d..2a2ef25 100644 --- a/pages/store/[id]/index.vue +++ b/pages/store/[id]/index.vue @@ -44,7 +44,7 @@ type="button" class="inline-flex items-center gap-x-2 rounded-md bg-zinc-800 px-3 py-1 text-sm font-semibold font-display text-white shadow-sm hover:bg-zinc-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 duration-200 hover:scale-105 active:scale-95" > - Open in Admin Dashboard + {{ $t("store.openAdminDashboard") }}