Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2129cee5c4 | ||
|
|
3da110d6cc |
@@ -73,6 +73,7 @@ jobs:
|
||||
run: |
|
||||
npm ci
|
||||
npm run build:android
|
||||
zip -r dist.zip dist
|
||||
|
||||
- name: Sync Capacitor to Android
|
||||
working-directory: client
|
||||
@@ -105,4 +106,5 @@ jobs:
|
||||
- Client: `${{ vars.REGISTRY }}/${{ vars.CLIENT_IMAGE }}:latest`
|
||||
files: |
|
||||
client/android/app/build/outputs/apk/release/*.apk
|
||||
client/dist.zip
|
||||
api_key: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -9,7 +9,8 @@ android {
|
||||
|
||||
apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
|
||||
dependencies {
|
||||
|
||||
implementation project(':capacitor-app')
|
||||
implementation project(':capgo-capacitor-updater')
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN
|
||||
include ':capacitor-android'
|
||||
project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')
|
||||
|
||||
include ':capacitor-app'
|
||||
project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/android')
|
||||
|
||||
include ':capgo-capacitor-updater'
|
||||
project(':capgo-capacitor-updater').projectDir = new File('../node_modules/@capgo/capacitor-updater/android')
|
||||
|
||||
@@ -5,5 +5,10 @@
|
||||
"server": {
|
||||
"androidScheme": "https",
|
||||
"cleartext": false
|
||||
},
|
||||
"plugins": {
|
||||
"CapacitorUpdater": {
|
||||
"autoUpdate": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
20
client/package-lock.json
generated
20
client/package-lock.json
generated
@@ -9,7 +9,9 @@
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@capacitor/android": "^8.0.0",
|
||||
"@capacitor/app": "^8.0.0",
|
||||
"@capacitor/core": "^8.0.0",
|
||||
"@capgo/capacitor-updater": "^8.40.6",
|
||||
"@eslint/eslintrc": "^3.3.3",
|
||||
"@eslint/js": "^9.39.2",
|
||||
"@mdi/font": "^7.3.67",
|
||||
@@ -639,6 +641,15 @@
|
||||
"@capacitor/core": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@capacitor/app": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/app/-/app-8.0.0.tgz",
|
||||
"integrity": "sha512-OwzIkUs4w433Bu9WWAEbEYngXEfJXZ9Wmdb8eoaqzYBgB0W9/3Ed/mh6sAYPNBAZlpyarmewgP7Nb+d3Vrh+xA==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@capacitor/core": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@capacitor/cli": {
|
||||
"version": "7.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/cli/-/cli-7.4.4.tgz",
|
||||
@@ -681,6 +692,15 @@
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@capgo/capacitor-updater": {
|
||||
"version": "8.40.6",
|
||||
"resolved": "https://registry.npmjs.org/@capgo/capacitor-updater/-/capacitor-updater-8.40.6.tgz",
|
||||
"integrity": "sha512-Z2uG8E9VKClYeZRhvkN8p/w3tXqxj5DB61M3uKwuHyHgPWEOoBv+drlRtnwDL8+XhSljNLG7yGPWUg8WAi8cBQ==",
|
||||
"license": "MPL-2.0",
|
||||
"peerDependencies": {
|
||||
"@capacitor/core": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@csstools/css-parser-algorithms": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz",
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@capacitor/android": "^8.0.0",
|
||||
"@capacitor/app": "^8.0.0",
|
||||
"@capacitor/core": "^8.0.0",
|
||||
"@capgo/capacitor-updater": "^8.40.6",
|
||||
"@eslint/eslintrc": "^3.3.3",
|
||||
"@eslint/js": "^9.39.2",
|
||||
"@mdi/font": "^7.3.67",
|
||||
|
||||
@@ -287,7 +287,9 @@ import {
|
||||
ref, watch, onMounted, computed, onUnmounted,
|
||||
} from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { App as CapacitorApp } from '@capacitor/app';
|
||||
import { useAppStore } from '@/stores/appStore';
|
||||
import { checkForUpdates } from '@/utils/autoUpdate';
|
||||
import logo from '@/assets/icon.svg';
|
||||
|
||||
const drawer = ref(false);
|
||||
@@ -388,6 +390,9 @@ const handleMouseMove = (e) => {
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
CapacitorApp.addListener('appStateChange', ({ isActive }) => {
|
||||
if (isActive) checkForUpdates();
|
||||
});
|
||||
if (store.token) {
|
||||
viewState.value = 'app';
|
||||
store.fetchStats();
|
||||
|
||||
@@ -25,10 +25,10 @@ const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: [
|
||||
{ path: '/', component: Dashboard },
|
||||
{ path: '/dashboard', component: Dashboard },
|
||||
{ path: '/collection', component: Collection },
|
||||
{ path: '/review', component: Review },
|
||||
{ path: '/lesson', component: Lesson },
|
||||
{ path: '/:pathMatch(.*)*', redirect: '/' },
|
||||
],
|
||||
});
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
.v-navigation-drawer {
|
||||
background-color: $color-surface !important;
|
||||
border-right: $border-width-sm solid $color-border;
|
||||
padding-top: env(safe-area-inset-top) !important;
|
||||
|
||||
.v-list-item--active {
|
||||
background-color: $bg-glass-strong;
|
||||
|
||||
55
client/src/utils/autoUpdate.js
Normal file
55
client/src/utils/autoUpdate.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import { Capacitor } from '@capacitor/core';
|
||||
import { App } from '@capacitor/app';
|
||||
|
||||
export async function checkForUpdates() {
|
||||
if (!Capacitor.isNativePlatform()) {
|
||||
console.log('Auto-update skipped (running on web)');
|
||||
return;
|
||||
}
|
||||
|
||||
function isNewer(current, target) {
|
||||
const c = current.replace(/^v/, '').split('.').map(Number);
|
||||
const t = target.replace(/^v/, '').split('.').map(Number);
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (t[i] > c[i]) return true;
|
||||
if (t[i] < c[i]) return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const { CapacitorUpdater } = await import('@capgo/capacitor-updater');
|
||||
|
||||
await CapacitorUpdater.notifyAppReady();
|
||||
|
||||
const GITEA_API_URL = 'https://git.crylia.de/Crylia/zen-kanji/releases/latest';
|
||||
|
||||
const appInfo = await App.getInfo();
|
||||
const currentVersion = appInfo.version;
|
||||
|
||||
const response = await fetch(GITEA_API_URL);
|
||||
if (!response.ok) return;
|
||||
|
||||
const release = await response.json();
|
||||
const latestTag = release.tag_name;
|
||||
|
||||
if (!isNewer(currentVersion, latestTag)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const asset = release.assets.find((a) => a.name === 'dist.zip');
|
||||
if (!asset) return;
|
||||
|
||||
console.log(`Downloading update: ${latestTag}`);
|
||||
|
||||
const version = await CapacitorUpdater.download({
|
||||
url: asset.browser_download_url,
|
||||
version: latestTag,
|
||||
});
|
||||
|
||||
await CapacitorUpdater.set(version);
|
||||
} catch (error) {
|
||||
console.error('Auto-update failed:', error);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
v-else-if="currentItem"
|
||||
)
|
||||
.d-flex.align-center.pa-4.border-b-subtle
|
||||
v-btn(icon="mdi-close" variant="text" to="/dashboard" color="grey")
|
||||
v-btn(icon="mdi-close" variant="text" to="/" color="grey")
|
||||
v-spacer
|
||||
.text-caption.text-grey-darken-1.font-weight-bold
|
||||
| {{ sessionDone + 1 }} / {{ sessionTotal }}
|
||||
@@ -95,7 +95,7 @@
|
||||
.text-h4.font-weight-bold.text-white.mb-2 {{ $t('lesson.completeTitle') }}
|
||||
.text-body-1.text-grey.mb-8 {{ $t('lesson.learned', { n: sessionDone }) }}
|
||||
v-btn.glow-btn.text-black.font-weight-bold(
|
||||
to="/dashboard"
|
||||
to="/"
|
||||
block
|
||||
color="cyan"
|
||||
height="50"
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
.text-caption.text-grey.text-uppercase.mt-1 {{ $t('stats.correct') }}
|
||||
|
||||
v-btn.text-black.font-weight-bold.glow-btn(
|
||||
to="/dashboard"
|
||||
to="/"
|
||||
block
|
||||
color="primary"
|
||||
height="50"
|
||||
@@ -108,7 +108,7 @@
|
||||
.text-h4.mb-2.text-white {{ $t('review.caughtUp') }}
|
||||
.text-grey.mb-6 {{ $t('review.noReviews') }}
|
||||
v-btn.font-weight-bold(
|
||||
to="/dashboard"
|
||||
to="/"
|
||||
color="primary"
|
||||
variant="tonal"
|
||||
) {{ $t('review.viewCollection') }}
|
||||
|
||||
@@ -93,7 +93,7 @@ export const getUserStats = async (user) => {
|
||||
accuracy: Math.round((item.stats.correct / item.stats.total) * 100)
|
||||
})).filter(i => i.accuracy < 85)
|
||||
.sort((a, b) => a.accuracy - b.accuracy)
|
||||
.slice(0, 4);
|
||||
.slice(0, 10);
|
||||
|
||||
return {
|
||||
distribution: dist,
|
||||
|
||||
Reference in New Issue
Block a user