-
- ();
-const { tt } = useI18n();
+const { tt, getCurrentLanguageTextDirection } = useI18n();
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
const transactionTagsStore = useTransactionTagsStore();
@@ -181,6 +186,7 @@ const showDeleteActionSheet = ref(false);
const displayOrderModified = ref(false);
const displayOrderSaving = ref(false);
+const textDirection = computed(() => getCurrentLanguageTextDirection());
const tags = computed(() => transactionTagsStore.allTransactionTags);
const firstShowingId = computed(() => getFirstShowingId(tags.value, showHidden.value));
const lastShowingId = computed(() => getLastShowingId(tags.value, showHidden.value));
@@ -413,7 +419,7 @@ init();
diff --git a/src/views/mobile/users/SessionListPage.vue b/src/views/mobile/users/SessionListPage.vue
index 11d08605..1b2143bf 100644
--- a/src/views/mobile/users/SessionListPage.vue
+++ b/src/views/mobile/users/SessionListPage.vue
@@ -34,7 +34,9 @@
{{ session.lastSeenDateTime }}
-
+
@@ -51,6 +53,7 @@ import { useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from
import { useTokensStore } from '@/stores/token.ts';
+import { TextDirection } from '@/core/text.ts';
import { type TokenInfoResponse, SessionInfo } from '@/models/token.ts';
import { isEquals } from '@/lib/common.ts';
@@ -73,7 +76,7 @@ const props = defineProps<{
f7router: Router.Router;
}>();
-const { tt, formatUnixTimeToLongDateTime } = useI18n();
+const { tt, getCurrentLanguageTextDirection, formatUnixTimeToLongDateTime } = useI18n();
const { showConfirm, showToast, routeBackOnError } = useI18nUIComponents();
const tokensStore = useTokensStore();
@@ -82,6 +85,8 @@ const tokens = ref([]);
const loading = ref(true);
const loadingError = ref(null);
+const textDirection = computed(() => getCurrentLanguageTextDirection());
+
const sessions = computed(() => {
const sessions: MobilePageSessionInfo[] = [];
diff --git a/src/views/mobile/users/UserProfilePage.vue b/src/views/mobile/users/UserProfilePage.vue
index 42b45d3f..6cf3ec54 100644
--- a/src/views/mobile/users/UserProfilePage.vue
+++ b/src/views/mobile/users/UserProfilePage.vue
@@ -526,6 +526,7 @@ import { useRootStore } from '@/stores/index.ts';
import { useUserStore } from '@/stores/user.ts';
import { useAccountsStore } from '@/stores/account.ts';
+import { TextDirection } from '@/core/text.ts';
import type { LocalizedCurrencyInfo } from '@/core/currency.ts';
import type { UserProfileResponse } from '@/models/user.ts';
@@ -538,7 +539,15 @@ const props = defineProps<{
f7router: Router.Router;
}>();
-const { tt, getAllLanguageOptions, getAllCurrencies, getCurrencyName, formatFiscalYearStartToLongDay } = useI18n();
+const {
+ tt,
+ getCurrentLanguageTextDirection,
+ getAllLanguageOptions,
+ getAllCurrencies,
+ getCurrencyName,
+ formatFiscalYearStartToLongDay
+} = useI18n();
+
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
const {
@@ -661,6 +670,8 @@ function save(): void {
return;
}
+ const oldTextDirection: TextDirection = getCurrentLanguageTextDirection();
+
saving.value = true;
showLoading(() => saving.value);
@@ -671,7 +682,10 @@ function save(): void {
doAfterProfileUpdate(response.user);
showToast('Your profile has been successfully updated');
- router.back();
+
+ if (oldTextDirection === getCurrentLanguageTextDirection()) {
+ router.back(); // if text direction is changed, the page will be reloaded, so it don't need to go back
+ }
}).catch(error => {
saving.value = false;
hideLoading();
diff --git a/vite.config.ts b/vite.config.ts
index 2cb46107..0e346d0b 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,7 +1,7 @@
import fs from 'fs';
import { resolve } from 'path';
-import { type UserConfig, defineConfig } from 'vite'
+import { type UserConfig, type Plugin, defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue';
import vuetify from 'vite-plugin-vuetify';
import { VitePWA } from 'vite-plugin-pwa';
@@ -15,6 +15,53 @@ const SRC_DIR = resolve(__dirname, './src');
const PUBLIC_DIR = resolve(__dirname, './public');
const BUILD_DIR = resolve(__dirname, './dist',);
+function injectFramework7CssFile({ htmlFileName, placeHolders }: { htmlFileName: string, placeHolders: { name: string, srcFileName: string, distFileNamePrefix: string }[] }): Plugin[] {
+ return [
+ {
+ name: 'inject-framework7-css-file:serve',
+ apply: 'serve',
+ enforce: 'post',
+ transformIndexHtml(html: string): string {
+ for (const placeholder of placeHolders) {
+ html = html.replace(`{{${placeholder.name}}}`, `${placeholder.srcFileName}`);
+ }
+ return html;
+ }
+ },
+ {
+ name: 'inject-framework7-css-file:build',
+ apply: 'build',
+ enforce: 'post',
+ generateBundle(_, bundle): void {
+ const placeholderCssFilePathMap: Record = {};
+
+ for (const fileName of Object.keys(bundle)) {
+ for (const placeholder of placeHolders) {
+ if (fileName.startsWith(placeholder.distFileNamePrefix)) {
+ placeholderCssFilePathMap[placeholder.name] = fileName;
+ break;
+ }
+ }
+ }
+
+ const htmlAsset = bundle[htmlFileName];
+
+ if (!htmlAsset || htmlAsset.type !== 'asset') {
+ return;
+ }
+
+ let html = htmlAsset.source as string;
+
+ for (const [placeholder, filePath] of Object.entries(placeholderCssFilePathMap)) {
+ html = html.replace(`{{${placeholder}}}`, `./${filePath}`);
+ }
+
+ htmlAsset.source = html;
+ }
+ }
+ ];
+}
+
export default defineConfig(() => {
const licenseContent = fs.readFileSync('./LICENSE', { encoding: 'utf-8' });
const buildUnixTime = process.env['buildUnixTime'] || '';
@@ -44,6 +91,21 @@ export default defineConfig(() => {
configFile: 'styles/desktop/configured-variables/_vuetify.scss'
}
}),
+ injectFramework7CssFile({
+ htmlFileName: 'mobile.html',
+ placeHolders: [
+ {
+ name: 'framework7-ltr-css-filepath',
+ srcFileName: 'mobile-ltr.scss',
+ distFileNamePrefix: 'css/vendor-framework7-ltr'
+ },
+ {
+ name: 'framework7-rtl-css-filepath',
+ srcFileName: 'mobile-rtl.scss',
+ distFileNamePrefix: 'css/vendor-framework7-rtl'
+ }
+ ]
+ }),
Checker({
vueTsc: true
}),
@@ -141,7 +203,9 @@ export default defineConfig(() => {
input: {
index: resolve(SRC_DIR, 'index.html'),
desktop: resolve(SRC_DIR, 'desktop.html'),
- mobile: resolve(SRC_DIR, 'mobile.html')
+ mobile: resolve(SRC_DIR, 'mobile.html'),
+ 'vendor-framework7-ltr': resolve(SRC_DIR, 'mobile-ltr.scss'),
+ 'vendor-framework7-rtl': resolve(SRC_DIR, 'mobile-rtl.scss')
},
output: {
assetFileNames: assetInfo => {