mobile version supports rtl

This commit is contained in:
MaysWind
2025-08-19 23:56:28 +08:00
parent efe39c7390
commit 13d5759e84
44 changed files with 534 additions and 219 deletions
@@ -363,13 +363,13 @@ function toggleLegend(legend: TrendsBarChartLegend): void {
<style>
.monthly-trends-bar-chart-legend {
margin-right: 4px;
margin-inline-end: 4px;
cursor: pointer;
}
.monthly-trends-bar-chart-legend-icon.f7-icons {
font-size: var(--ebk-trends-bar-chart-legend-icon-font-size);
margin-right: 2px;
margin-inline-end: 2px;
}
.monthly-trends-bar-chart-legend-unselected .monthly-trends-bar-chart-legend-icon.f7-icons {
+2 -2
View File
@@ -57,7 +57,7 @@
</f7-button>
<f7-button class="numpad-button numpad-button-num" @click="backspace" @taphold="clear()">
<span class="numpad-button-text numpad-button-text-normal">
<f7-icon f7="delete_left"></f7-icon>
<f7-icon class="icon-with-direction" f7="delete_left"></f7-icon>
</span>
</f7-button>
<f7-button class="numpad-button numpad-button-confirm no-right-border no-bottom-border" fill @click="confirm()">
@@ -400,7 +400,7 @@ watch(() => props.flipNegative, (newValue) => {
.numpad-value {
display: flex;
position: relative;
padding-left: 16px;
padding-inline-start: 16px;
line-height: 1;
height: var(--ebk-numpad-value-height);
align-items: center;
+5 -5
View File
@@ -40,7 +40,7 @@
<div class="pie-chart-toolbox-container padding-horizontal" v-if="showSelectedItemInfo">
<div class="pie-chart-toolbox">
<f7-link class="pie-chart-toolbox-button" :class="{ 'disabled': !!skeleton || !validItems || validItems.length <= 1 }" @click="switchSelectedItem(1)">
<f7-icon f7="arrow_left"></f7-icon>
<f7-icon class="icon-with-direction" f7="arrow_left"></f7-icon>
</f7-link>
<div class="pie-chart-toolbox-info">
@@ -61,7 +61,7 @@
<span v-else-if="!skeleton && selectedItem.displayName">{{ selectedItem.displayName }}</span>
<span class="skeleton-text" v-if="skeleton">Value</span>
<span v-else-if="!skeleton && showValue" :style="getColorStyle(selectedItem ? selectedItem.color : '')">{{ selectedItem.displayValue }}</span>
<f7-icon class="item-navigate-icon" f7="chevron_right" v-if="enableClickItem"></f7-icon>
<f7-icon class="item-navigate-icon icon-with-direction" f7="chevron_right" v-if="enableClickItem"></f7-icon>
</f7-link>
<f7-link :no-link-class="true" v-else-if="!validItems || !validItems.length">
{{ tt('No transaction data') }}
@@ -69,7 +69,7 @@
</div>
<f7-link class="pie-chart-toolbox-button" :class="{ 'disabled': !!skeleton || !validItems || validItems.length <= 1 }" @click="switchSelectedItem(-1)">
<f7-icon f7="arrow_right"></f7-icon>
<f7-icon class="icon-with-direction" f7="arrow_right"></f7-icon>
</f7-link>
</div>
</div>
@@ -264,14 +264,14 @@ function clickItem(item: CommonPieChartDataItem): void {
}
.pie-chart-toolbox-info a > span + span {
padding-left: 8px;
padding-inline-start: 8px;
}
.pie-chart-toolbox-info .item-navigate-icon {
color: rgba(0, 0, 0, 0.2);
font-size: 18px;
font-weight: bold;
padding-left: 4px;
padding-inline-start: 4px;
}
.pie-chart-toolbox-button {
+4 -4
View File
@@ -82,13 +82,13 @@ watch(() => props.modelValue, (newValue) => {
<style>
.list-item-pincode-input .item-content {
padding-left: 0;
padding-right: 0;
padding-inline-start: 0;
padding-inline-end: 0;
}
.list-item-pincode-input .item-content .item-inner {
padding-left: 0;
padding-right: 0;
padding-inline-start: 0;
padding-inline-end: 0;
justify-content: center;
}
</style>
@@ -21,7 +21,7 @@
v-for="type in allTransactionScheduledFrequencyTypes"
@click="changeFrequencyType(type.type)">
<template #after>
<f7-icon class="list-item-showing" f7="chevron_right" v-if="currentFrequencyType === type.type"></f7-icon>
<f7-icon class="list-item-showing icon-with-direction" f7="chevron_right" v-if="currentFrequencyType === type.type"></f7-icon>
</template>
</f7-list-item>
</f7-list>
@@ -165,10 +165,10 @@ function onSheetClosed(): void {
}
.schedule-frequency-type-list.list .item-inner {
padding-right: 6px;
padding-inline-end: 6px;
}
.schedule-frequency-value-list-list.list .item-content {
padding-left: 0;
padding-inline-start: 0;
}
</style>
@@ -37,7 +37,7 @@
<f7-block class="no-padding no-margin">
<div class="display-flex">
<f7-icon class="transaction-tag-icon" f7="number"></f7-icon>
<div class="tag-selection-list-item list-item-valign-middle padding-left-half">
<div class="tag-selection-list-item list-item-valign-middle padding-inline-start-half">
{{ tag.name }}
</div>
</div>
@@ -55,7 +55,7 @@
</template>
<template #title>
<div class="display-flex">
<f7-input class="list-title-input padding-left-half"
<f7-input class="list-title-input padding-inline-start-half"
type="text"
:placeholder="tt('Tag Title')"
v-model:value="newTag.name"
@@ -70,7 +70,7 @@
color="blue"
@click="saveNewTag()">
</f7-button>
<f7-button class="no-padding margin-left-half"
<f7-button class="no-padding margin-inline-start-half"
raised fill
icon-f7="xmark"
color="gray"
@@ -261,7 +261,7 @@ function onSheetClosed(): void {
}
.tag-selection-list.list .item-media + .item-inner {
margin-left: 0;
margin-inline-start: 0;
}
.tag-selection-list-item {
@@ -34,7 +34,7 @@
<ItemIcon :icon-type="primaryIconType" :icon-id="primaryIconField ? item[primaryIconField] : undefined" :color="primaryColorField ? item[primaryColorField] : undefined"></ItemIcon>
</template>
<template #after>
<f7-icon class="list-item-showing" f7="chevron_right" v-if="item === selectedPrimaryItem"></f7-icon>
<f7-icon class="list-item-showing icon-with-direction" f7="chevron_right" v-if="item === selectedPrimaryItem"></f7-icon>
</template>
</f7-list-item>
<f7-list-item v-if="!filteredItems || !filteredItems.length"
@@ -160,10 +160,10 @@ function onSheetClosed(): void {
}
.primary-list.list .item-inner {
padding-right: 6px;
padding-inline-end: 6px;
}
.secondary-list.list .item-content {
padding-left: 0;
padding-inline-start: 0;
}
</style>
+14
View File
@@ -13,6 +13,7 @@ import {
} from '@/core/setting.ts';
const settingsLocalStorageKey: string = 'ebk_app_settings';
const currentLanguageSessionStorageKey: string = 'ebk_current_language';
function getStoredApplicationSettings(): BaseApplicationSetting {
try {
@@ -101,3 +102,16 @@ export function isEnableAnimate(): boolean {
export function clearSettings(): void {
localStorage.removeItem(settingsLocalStorageKey);
}
export function getSessionCurrentLanguageKey(): string {
return sessionStorage.getItem(currentLanguageSessionStorageKey) || '';
}
export function setSessionCurrentLanguageKey(languageKey: string): void {
if (!languageKey) {
sessionStorage.removeItem(currentLanguageSessionStorageKey);
return;
}
sessionStorage.setItem(currentLanguageSessionStorageKey, languageKey);
}
+30 -23
View File
@@ -4,6 +4,7 @@ import type { Dialog, Picker, Router } from 'framework7/types';
import { useI18n } from '@/locales/helpers.ts';
import { TextDirection } from '@/core/text.ts';
import { FontSize, FONT_SIZE_PREVIEW_CLASSNAME_PREFIX } from '@/core/font.ts';
import { getNumberValue } from '../common.ts';
import { isEnableAnimate } from '../settings.ts';
@@ -195,7 +196,7 @@ export function onInfiniteScrolling(callback: (e: Event) => void): void {
}
export function useI18nUIComponents() {
const { tt, te } = useI18n();
const { tt, te, getCurrentLanguageTextDirection } = useI18n();
function routeBackOnError<T>(f7router: Router.Router, errorRef: Ref<T>): void {
const unwatch = watch(errorRef, (newValue) => {
@@ -230,34 +231,32 @@ export function useI18nUIComponents() {
}
function showConfirm(message: string, confirmCallback?: (dialog: Dialog.Dialog, e: Event) => void, cancelCallback?: (dialog: Dialog.Dialog, e: Event) => void): void {
const textDirection = getCurrentLanguageTextDirection();
const cancelButton: Dialog.DialogButton = {
text: tt('Cancel'),
onClick: cancelCallback
};
const confirmButton: Dialog.DialogButton = {
text: tt('OK'),
onClick: confirmCallback
};
f7ready((f7) => {
f7.dialog.create({
title: tt('global.app.title'),
text: tt(message),
animate: isEnableAnimate(),
buttons: [
{
text: tt('Cancel'),
onClick: cancelCallback
},
{
text: tt('OK'),
onClick: confirmCallback
}
]
buttons: textDirection == TextDirection.RTL ? [confirmButton, cancelButton] : [cancelButton, confirmButton]
}).open();
});
}
function showPrompt(message: string, currentValue?: string, confirmCallback?: (value: string, dialog: Dialog.Dialog, e: Event) => void, cancelCallback?: (value: string, dialog: Dialog.Dialog, e: Event) => void): void {
f7ready((f7) => {
f7.dialog.create({
title: tt('global.app.title'),
text: tt(message),
content: `<div class="dialog-input-field input"><input type="text" class="dialog-input" value="${currentValue || ''}"></div>`,
animate: isEnableAnimate(),
buttons: [
{
const textDirection = getCurrentLanguageTextDirection();
const cancelButton: Dialog.DialogButton = {
text: tt('Cancel'),
onClick: (dialog, event) => {
if (cancelCallback) {
@@ -265,8 +264,9 @@ export function useI18nUIComponents() {
cancelCallback(inputValue, dialog, event);
}
}
},
{
};
const confirmButton: Dialog.DialogButton = {
text: tt('OK'),
onClick: (dialog, event) => {
if (confirmCallback) {
@@ -274,8 +274,15 @@ export function useI18nUIComponents() {
confirmCallback(inputValue, dialog, event);
}
}
}
]
};
f7ready((f7) => {
f7.dialog.create({
title: tt('global.app.title'),
text: tt(message),
content: `<div class="dialog-input-field input"><input type="text" class="dialog-input" value="${currentValue || ''}"></div>`,
animate: isEnableAnimate(),
buttons: textDirection == TextDirection.RTL ? [confirmButton, cancelButton] : [cancelButton, confirmButton]
}).open();
});
}
+26
View File
@@ -190,6 +190,11 @@ import {
getAllFilteredAccountsBalance
} from '@/lib/account.ts';
import {
getSessionCurrentLanguageKey,
setSessionCurrentLanguageKey
} from '@/lib/settings.ts';
import services from '@/lib/services.ts';
import logger from '@/lib/logger.ts';
@@ -1961,14 +1966,31 @@ export function useI18n() {
}
});
setSessionCurrentLanguageKey(languageKey);
services.setLocale(languageKey);
document.querySelector('html')?.setAttribute('lang', languageKey);
if (document.querySelector('html')?.getAttribute('data-dir-mode') === 'isolate') {
if (languageInfo && languageInfo.textDirection === TextDirection.LTR) {
if (location.search.includes('rtl')) {
const url = new URL(window.location.href);
url.search = '';
window.location.replace(url.toString());
}
} else if (languageInfo && languageInfo.textDirection === TextDirection.RTL) {
if (!location.search.includes('rtl')) {
const url = new URL(window.location.href);
url.searchParams.set('rtl', '');
window.location.replace(url.toString());
}
}
} else {
if (languageInfo && languageInfo.textDirection === TextDirection.LTR) {
document.querySelector('html')?.removeAttribute('dir');
} else if (languageInfo && languageInfo.textDirection === TextDirection.RTL) {
document.querySelector('html')?.setAttribute('dir', 'rtl');
}
}
const defaultCurrency = getDefaultCurrency();
const defaultFirstDayOfWeekName = getDefaultFirstDayOfWeek();
@@ -2003,11 +2025,15 @@ export function useI18n() {
}
function initLocale(lastUserLanguage?: string, timezone?: string): LocaleDefaultSettings | null {
const sessionLanguageKey: string = getSessionCurrentLanguageKey();
let localeDefaultSettings: LocaleDefaultSettings | null = null;
if (lastUserLanguage && getLanguageInfo(lastUserLanguage)) {
logger.info(`Last user language is ${lastUserLanguage}`);
localeDefaultSettings = setLanguage(lastUserLanguage, true);
} else if (sessionLanguageKey && getLanguageInfo(sessionLanguageKey)) {
logger.info(`Session language is ${sessionLanguageKey}`);
localeDefaultSettings = setLanguage(sessionLanguageKey, true);
} else {
localeDefaultSettings = setLanguage(null, true);
}
+33
View File
@@ -0,0 +1,33 @@
@import 'framework7/css';
@import 'framework7/components/dialog/css';
@import 'framework7/components/popup/css';
@import 'framework7/components/login-screen/css';
@import 'framework7/components/popover/css';
@import 'framework7/components/actions/css';
@import 'framework7/components/sheet/css';
@import 'framework7/components/notification/css';
@import 'framework7/components/toast/css';
@import 'framework7/components/preloader/css';
@import 'framework7/components/progressbar/css';
@import 'framework7/components/sortable/css';
@import 'framework7/components/swipeout/css';
@import 'framework7/components/accordion/css';
@import 'framework7/components/card/css';
@import 'framework7/components/chip/css';
@import 'framework7/components/form/css';
@import 'framework7/components/input/css';
@import 'framework7/components/checkbox/css';
@import 'framework7/components/radio/css';
@import 'framework7/components/toggle/css';
@import 'framework7/components/range/css';
@import 'framework7/components/grid/css';
@import 'framework7/components/picker/css';
@import 'framework7/components/infinite-scroll/css';
@import 'framework7/components/pull-to-refresh/css';
@import 'framework7/components/searchbar/css';
@import 'framework7/components/tooltip/css';
@import 'framework7/components/skeleton/css';
@import 'framework7/components/treeview/css';
@import 'framework7/components/typography/css';
@import 'framework7/components/swiper/css';
@import 'framework7/components/photo-browser/css';
+9 -43
View File
@@ -39,40 +39,6 @@ import Framework7PhotoBrowser from 'framework7/components/photo-browser';
// @ts-expect-error there is a function called "registerComponents" in the framework7-vue package, but it is not declared in the type definition file
import Framework7Vue, { registerComponents } from 'framework7-vue/bundle';
import 'framework7/css';
import 'framework7/components/dialog/css';
import 'framework7/components/popup/css';
import 'framework7/components/login-screen/css';
import 'framework7/components/popover/css';
import 'framework7/components/actions/css';
import 'framework7/components/sheet/css';
import 'framework7/components/notification/css';
import 'framework7/components/toast/css';
import 'framework7/components/preloader/css';
import 'framework7/components/progressbar/css';
import 'framework7/components/sortable/css';
import 'framework7/components/swipeout/css';
import 'framework7/components/accordion/css';
import 'framework7/components/card/css';
import 'framework7/components/chip/css';
import 'framework7/components/form/css';
import 'framework7/components/input/css';
import 'framework7/components/checkbox/css';
import 'framework7/components/radio/css';
import 'framework7/components/toggle/css';
import 'framework7/components/range/css';
import 'framework7/components/grid/css';
import 'framework7/components/picker/css';
import 'framework7/components/infinite-scroll/css';
import 'framework7/components/pull-to-refresh/css';
import 'framework7/components/searchbar/css';
import 'framework7/components/tooltip/css';
import 'framework7/components/skeleton/css';
import 'framework7/components/treeview/css';
import 'framework7/components/typography/css';
import 'framework7/components/swiper/css';
import 'framework7/components/photo-browser/css';
import 'framework7-icons';
import 'line-awesome/dist/line-awesome/css/line-awesome.css';
@@ -113,15 +79,15 @@ import AccountBalanceTrendsBarChart from '@/components/mobile/AccountBalanceTren
import TextareaAutoSize from '@/directives/mobile/textareaAutoSize.ts';
import '@/styles/mobile/global.css';
import '@/styles/mobile/font-size-default.css';
import '@/styles/mobile/font-size-small.css';
import '@/styles/mobile/font-size-large.css';
import '@/styles/mobile/font-size-x-large.css';
import '@/styles/mobile/font-size-xx-large.css';
import '@/styles/mobile/font-size-xxx-large.css';
import '@/styles/mobile/font-size-xxxx-large.css';
import '@/styles/mobile/amount-color.css';
import '@/styles/mobile/global.scss';
import '@/styles/mobile/font-size-default.scss';
import '@/styles/mobile/font-size-small.scss';
import '@/styles/mobile/font-size-large.scss';
import '@/styles/mobile/font-size-x-large.scss';
import '@/styles/mobile/font-size-xx-large.scss';
import '@/styles/mobile/font-size-xxx-large.scss';
import '@/styles/mobile/font-size-xxxx-large.scss';
import '@/styles/mobile/amount-color.scss';
import App from '@/MobileApp.vue';
+33
View File
@@ -0,0 +1,33 @@
@import '../node_modules/framework7/framework7-rtl.css';
@import '../node_modules/framework7/components/dialog/dialog-rtl.css';
@import '../node_modules/framework7/components/popup/popup-rtl.css';
@import '../node_modules/framework7/components/login-screen/login-screen-rtl.css';
@import '../node_modules/framework7/components/popover/popover-rtl.css';
@import '../node_modules/framework7/components/actions/actions-rtl.css';
@import '../node_modules/framework7/components/sheet/sheet-rtl.css';
@import '../node_modules/framework7/components/notification/notification-rtl.css';
@import '../node_modules/framework7/components/toast/toast-rtl.css';
@import '../node_modules/framework7/components/preloader/preloader-rtl.css';
@import '../node_modules/framework7/components/progressbar/progressbar-rtl.css';
@import '../node_modules/framework7/components/sortable/sortable-rtl.css';
@import '../node_modules/framework7/components/swipeout/swipeout-rtl.css';
@import '../node_modules/framework7/components/accordion/accordion-rtl.css';
@import '../node_modules/framework7/components/card/card-rtl.css';
@import '../node_modules/framework7/components/chip/chip-rtl.css';
@import '../node_modules/framework7/components/form/form-rtl.css';
@import '../node_modules/framework7/components/input/input-rtl.css';
@import '../node_modules/framework7/components/checkbox/checkbox-rtl.css';
@import '../node_modules/framework7/components/radio/radio-rtl.css';
@import '../node_modules/framework7/components/toggle/toggle-rtl.css';
@import '../node_modules/framework7/components/range/range-rtl.css';
@import '../node_modules/framework7/components/grid/grid-rtl.css';
@import '../node_modules/framework7/components/picker/picker-rtl.css';
@import '../node_modules/framework7/components/infinite-scroll/infinite-scroll-rtl.css';
@import '../node_modules/framework7/components/pull-to-refresh/pull-to-refresh-rtl.css';
@import '../node_modules/framework7/components/searchbar/searchbar-rtl.css';
@import '../node_modules/framework7/components/tooltip/tooltip-rtl.css';
@import '../node_modules/framework7/components/skeleton/skeleton-rtl.css';
@import '../node_modules/framework7/components/treeview/treeview-rtl.css';
@import '../node_modules/framework7/components/typography/typography-rtl.css';
@import '../node_modules/framework7/components/swiper/swiper-rtl.css';
@import '../node_modules/framework7/components/photo-browser/photo-browser-rtl.css';
+12
View File
@@ -58,6 +58,18 @@
<link rel="apple-touch-startup-image" media="screen and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="img/splash_screens/9.7__iPad_Pro__7.9__iPad_mini__9.7__iPad_Air__9.7__iPad_portrait.png">
<link rel="apple-touch-startup-image" media="screen and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="img/splash_screens/8.3__iPad_Mini_portrait.png">
<link rel="manifest" href="manifest.json">
<link id="framework7-css" rel="stylesheet" crossorigin>
<script>
document.querySelector('html').setAttribute('data-dir-mode', 'isolate');
if (location.search.includes('rtl')) {
document.querySelector('html').setAttribute('dir', 'rtl');
document.getElementById('framework7-css').href = '{{framework7-rtl-css-filepath}}';
} else {
document.querySelector('html').removeAttribute('dir');
document.getElementById('framework7-css').href = '{{framework7-ltr-css-filepath}}';
}
</script>
<script src="./server_settings.js"></script>
</head>
<body>
@@ -21,6 +21,38 @@ input[type=number] {
}
/** Common class **/
.margin-inline-start {
margin-inline-start: var(--f7-typography-margin) !important;
}
.margin-inline-start-half {
margin-inline-start: calc(var(--f7-typography-margin) / 2) !important;
}
.margin-inline-end {
margin-inline-end: var(--f7-typography-margin) !important;
}
.margin-inline-end-half {
margin-inline-end: calc(var(--f7-typography-margin) / 2) !important;
}
.padding-inline-start {
padding-inline-start: var(--f7-typography-padding) !important;
}
.padding-inline-start-half {
padding-inline-start: calc(var(--f7-typography-padding) / 2) !important;
}
.padding-inline-end {
padding-inline-end: var(--f7-typography-padding) !important;
}
.padding-inline-end-half {
padding-inline-end: calc(var(--f7-typography-padding) / 2) !important;
}
.no-right-border {
border-right: 0;
}
@@ -234,6 +266,10 @@ i.icon.la, i.icon.las, i.icon.lab {
}
}
html[dir="rtl"] i.icon.icon-with-direction {
transform: scaleX(-1);
}
/** Replacing the default style of @vuepic/vue-datepicker **/
.dp__theme_light {
--dp-primary-color: #c67e48;
@@ -245,12 +281,12 @@ i.icon.la, i.icon.las, i.icon.lab {
/** Common class for replacing the default style of framework7 **/
.navbar .navbar-compact-icons.right a + a {
margin-left: 0;
margin-inline-start: 0;
}
.toolbar-item-auto-size .toolbar-inner {
padding-left: 16px;
padding-right: 16px;
padding-inline-start: 16px;
padding-inline-end: 16px;
gap: 4px;
}
@@ -402,11 +438,22 @@ i.icon.la, i.icon.las, i.icon.lab {
.list .item-content .list-item-checked-icon {
font-size: var(--ebk-list-item-checked-icon-font-size);
color: var(--f7-radio-active-color, var(--f7-theme-color));
margin-right: calc(var(--f7-list-item-media-margin) + var(--f7-checkbox-extra-margin));
}
html:not([dir="rtl"]) .list .item-content .list-item-checked-icon {
margin-inline-end: calc(var(--f7-list-item-media-margin) + var(--f7-checkbox-extra-margin));
}
html[dir="rtl"] .list .item-content .list-item-checked-icon {
margin-inline-start: calc(var(--f7-list-item-media-margin) + var(--f7-checkbox-extra-margin));
}
.list .item-content > .item-inner > .item-after .list-item-checked-icon {
margin-right: 0;
margin-inline-end: 0;
}
html[dir="rtl"] .list .item-content > .item-inner > .item-after .list-item-checked-icon {
margin-inline-start: 0;
}
.list li.no-margin .item-content.item-input {
@@ -435,7 +482,7 @@ i.icon.la, i.icon.las, i.icon.lab {
}
.icon-after-text {
margin-left: 6px;
margin-inline-start: 6px;
}
.icon-after-text i.icon {
@@ -443,12 +490,22 @@ i.icon.la, i.icon.las, i.icon.lab {
}
.badge.right-bottom-icon {
margin-left: -12px;
margin-inline-start: -12px;
margin-top: 14px;
width: 16px;
height: 16px;
}
html[dir="rtl"] .badge.right-bottom-icon {
left: unset;
right: 50%;
}
html[dir="rtl"] .icon.las .badge.right-bottom-icon {
right: 100%;
margin-inline-start: -14px;
}
.badge.right-bottom-icon > .icon {
font-size: var(--ebk-right-bottom-icon-font-size);
width: var(--ebk-right-bottom-icon-font-size);
@@ -472,7 +529,7 @@ i.icon.la, i.icon.las, i.icon.lab {
position: absolute;
left: 50%;
top: 50%;
margin-left: -18px;
margin-inline-start: -18px;
margin-top: -8px;
border-radius: 3px;
background: #666
@@ -493,19 +550,19 @@ i.icon.la, i.icon.las, i.icon.lab {
}
.list-item-with-multi-item .list-item-subitem:first-child .item-content {
padding-left: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
padding-inline-start: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
}
.list-item-with-multi-item .list-item-subitem .item-inner {
display: block;
width: 100%;
padding-left: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
padding-inline-start: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
padding-top: var(--f7-list-item-padding-vertical);
padding-bottom: var(--f7-list-item-padding-vertical);
}
.list-item-with-multi-item .list-item-subitem:first-child .item-inner {
padding-left: 0;
padding-inline-start: 0;
}
/** Combination list for framework7 **/
@@ -544,8 +601,12 @@ i.icon.la, i.icon.las, i.icon.lab {
border-radius: var(--f7-list-inset-border-radius);
}
.combination-list-wrapper .list.combination-list-header .combination-list-chevron-icon {
margin-left: auto;
html:not([dir="rtl"]) .combination-list-wrapper .list.combination-list-header .combination-list-chevron-icon {
margin-inline-start: auto;
}
html[dir="rtl"] .combination-list-wrapper .list.combination-list-header .combination-list-chevron-icon {
margin-inline-end: auto;
}
.combination-list-wrapper .list.combination-list-content.inset > ul {
@@ -576,7 +637,7 @@ i.icon.la, i.icon.las, i.icon.lab {
}
.nested-list-item.has-child-list-item .item-link .item-inner {
padding-right: 0;
padding-inline-end: 0;
}
.nested-list-item.has-child-list-item .item-link .item-inner:before {
@@ -589,7 +650,7 @@ i.icon.la, i.icon.las, i.icon.lab {
.nested-list-item.has-child-list-item .item-link .item-inner .nested-list-item-child .item-link .item-inner,
.nested-list-item.has-child-list-item .item-link .item-inner .nested-list-item-inner {
padding-right: calc(var(--f7-list-chevron-icon-area) + var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-right));
padding-inline-end: calc(var(--f7-list-chevron-icon-area) + var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-right));
}
.nested-list-item.has-child-list-item .item-link .item-inner .nested-list-item-child .item-link .item-inner:before {
@@ -603,13 +664,13 @@ i.icon.la, i.icon.las, i.icon.lab {
.nested-list-item .nested-list-item-title {
width: 100%;
flex-shrink: 1;
margin-right: var(--f7-list-item-media-margin);
margin-inline-end: var(--f7-list-item-media-margin);
overflow: hidden;
text-overflow: ellipsis;
}
.nested-list-item.has-child-list-item .nested-list-item-title {
margin-left: var(--f7-list-item-media-margin);
margin-inline-start: var(--f7-list-item-media-margin);
}
.nested-list-item .nested-list-item-after {
@@ -618,8 +679,8 @@ i.icon.la, i.icon.las, i.icon.lab {
display: flex;
font-size: var(--f7-list-item-after-font-size);
color: var(--f7-list-item-after-text-color);
margin-left: auto;
padding-left: var(--f7-list-item-after-padding);
margin-inline-start: auto;
padding-inline-start: var(--f7-list-item-after-padding);
}
.nested-list-item.has-child-list-item > .swipeout-content > .item-content > .item-inner:after,
@@ -654,7 +715,7 @@ i.icon.la, i.icon.las, i.icon.lab {
}
.sortable-enabled .nested-list-item .nested-list-item-child .item-inner {
padding-right: var(--f7-safe-area-right) !important;
padding-inline-end: var(--f7-safe-area-right) !important;
}
/** Fix @vuepic/vue-datepicker style issue **/
@@ -683,6 +744,10 @@ i.icon.la, i.icon.las, i.icon.lab {
width: 100%;
}
html[dir="rtl"] .dp__main .dp__btn.dp--arrow-btn-nav {
transform: scaleX(-1);
}
/* statistics-list */
.statistics-list-item-overview-amount {
margin-top: 2px;
@@ -709,7 +774,7 @@ i.icon.la, i.icon.las, i.icon.lab {
.statistics-percent {
font-size: 0.7em;
opacity: 0.6;
margin-left: 6px;
margin-inline-start: 6px;
}
.statistics-item-end {
@@ -719,7 +784,7 @@ i.icon.la, i.icon.las, i.icon.lab {
}
.statistics-percent-line {
margin-right: calc(var(--f7-list-chevron-icon-area) + var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-right));
margin-inline-end: calc(var(--f7-list-chevron-icon-area) + var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-right));
}
.statistics-percent-line .progressbar {
+4 -4
View File
@@ -21,7 +21,7 @@
<p class="no-margin">
<span class="month-expense" v-if="loading">0.00 USD</span>
<span class="month-expense" v-else-if="!loading">{{ transactionOverview && transactionOverview.thisMonth ? getDisplayExpenseAmount(transactionOverview.thisMonth) : '-' }}</span>
<f7-link class="margin-left-half" @click="showAmountInHomePage = !showAmountInHomePage">
<f7-link class="margin-inline-start-half" @click="showAmountInHomePage = !showAmountInHomePage">
<f7-icon class="ebk-hide-icon" :f7="showAmountInHomePage ? 'eye_slash_fill' : 'eye_fill'"></f7-icon>
</f7-link>
</p>
@@ -314,11 +314,11 @@ init();
}
.home-summary-misc > span {
margin-right: 4px;
margin-inline-end: 4px;
}
.home-summary-misc > span:last-child {
margin-right: 0;
margin-inline-end: 0;
}
.dark .home-summary-card {
@@ -348,7 +348,7 @@ init();
}
.overview-transaction-list .overview-transaction-footer > span {
margin-right: 4px;
margin-inline-end: 4px;
}
.overview-transaction-list .overview-transaction-amount {
+1 -1
View File
@@ -156,7 +156,7 @@
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
</template>
<f7-accordion-content v-if="category.subCategories.length" class="padding-left">
<f7-accordion-content v-if="category.subCategories.length" class="padding-inline-start-half">
<f7-list>
<f7-list-item :title="subCategory.name"
:key="subIdx"
+1 -1
View File
@@ -773,6 +773,6 @@ init();
}
.subaccount-delete-button {
margin-left: auto;
margin-inline-start: auto;
}
</style>
+16 -10
View File
@@ -19,7 +19,7 @@
<p class="no-margin">
<span class="net-assets" v-if="loading">0.00 USD</span>
<span class="net-assets" v-else-if="!loading">{{ netAssets }}</span>
<f7-link class="margin-left-half" @click="showAccountBalance = !showAccountBalance">
<f7-link class="margin-inline-start-half" @click="showAccountBalance = !showAccountBalance">
<f7-icon class="ebk-hide-icon" :f7="showAccountBalance ? 'eye_slash_fill' : 'eye_fill'"></f7-icon>
</f7-link>
</p>
@@ -44,7 +44,7 @@
<f7-list-item group-title :sortable="false">
<small>
<span>Account Category</span>
<span style="margin-left: 10px">0.00 USD</span>
<span style="margin-inline-start: 10px">0.00 USD</span>
</small>
</f7-list-item>
<f7-list-item class="nested-list-item" after="0.00 USD" link="#"
@@ -77,7 +77,7 @@
<f7-list-item group-title :sortable="false">
<small>
<span>{{ tt(accountCategory.name) }}</span>
<span style="margin-left: 10px">{{ accountCategoryTotalBalance(accountCategory) }}</span>
<span style="margin-inline-start: 10px">{{ accountCategoryTotalBalance(accountCategory) }}</span>
</small>
</f7-list-item>
<f7-list-item swipeout
@@ -137,16 +137,20 @@
</ul>
</li>
</template>
<f7-swipeout-actions left v-if="sortable">
<f7-swipeout-button :color="account.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
:right="textDirection === TextDirection.RTL"
v-if="sortable">
<f7-swipeout-button :color="account.hidden ? 'blue' : 'gray'" class="padding-horizontal"
overswipe close @click="hide(account, !account.hidden)">
<f7-icon :f7="account.hidden ? 'eye' : 'eye_slash'"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
<f7-swipeout-actions right v-if="!sortable">
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR"
v-if="!sortable">
<f7-swipeout-button color="orange" close :text="tt('Edit')" @click="edit(account)"></f7-swipeout-button>
<f7-swipeout-button color="primary" close :text="tt('More')" @click="showMoreActionSheetForAccount(account)"></f7-swipeout-button>
<f7-swipeout-button color="red" class="padding-left padding-right" @click="remove(account, false)">
<f7-swipeout-button color="red" class="padding-horizontal" @click="remove(account, false)">
<f7-icon f7="trash"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
@@ -207,6 +211,7 @@ import { useAccountListPageBaseBase } from '@/views/base/accounts/AccountListPag
import { useAccountsStore } from '@/stores/account.ts';
import { TextDirection } from '@/core/text.ts';
import { AccountType, AccountCategory } from '@/core/account.ts';
import type { Account, AccountShowingIds } from '@/models/account.ts';
@@ -216,7 +221,7 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt } = useI18n();
const { tt, getCurrentLanguageTextDirection } = useI18n();
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
const {
@@ -244,6 +249,7 @@ const showMoreActionSheet = ref<boolean>(false);
const showDeleteActionSheet = ref<boolean>(false);
const displayOrderSaving = ref<boolean>(false);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const firstShowingIds = computed<AccountShowingIds>(() => accountsStore.getFirstShowingIds(showHidden.value));
const lastShowingIds = computed<AccountShowingIds>(() => accountsStore.getLastShowingIds(showHidden.value));
const hasAnyVisibleAccount = computed<boolean>(() => accountsStore.allVisibleAccountsCount > 0);
@@ -487,11 +493,11 @@ init();
}
.account-overview-info > span {
margin-right: 4px;
margin-inline-end: 4px;
}
.account-overview-info > span:last-child {
margin-right: 0;
margin-inline-end: 0;
}
.account-list {
@@ -143,7 +143,7 @@
</div>
<div class="account-balance flex-shrink-1">
<span>Balance</span>
<span style="margin-left: 4px">0.00 USD</span>
<span style="margin-inline-start: 4px">0.00 USD</span>
</div>
</div>
</div>
@@ -229,14 +229,16 @@
</div>
<div class="account-balance flex-shrink-1">
<span>{{ isCurrentLiabilityAccount ? tt('Outstanding Balance') : tt('Balance') }}</span>
<span style="margin-left: 4px">{{ getDisplayAccountBalance(item.transaction) }}</span>
<span style="margin-inline-start: 4px">{{ getDisplayAccountBalance(item.transaction) }}</span>
</div>
</div>
</div>
</div>
</div>
</template>
<f7-swipeout-actions right v-if="item.type == 'transaction' && item.transaction">
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR"
v-if="item.type == 'transaction' && item.transaction">
<f7-swipeout-button color="primary" close
:text="tt('Duplicate')"
v-if="item.transaction.type !== TransactionType.ModifyBalance"
@@ -245,7 +247,7 @@
:text="tt('Edit')"
v-if="item.transaction.editable && item.transaction.type !== TransactionType.ModifyBalance"
@click="editTransaction(item.transaction)"></f7-swipeout-button>
<f7-swipeout-button color="red" class="padding-left padding-right"
<f7-swipeout-button color="red" class="padding-horizontal"
v-if="item.transaction.editable"
@click="removeTransaction(item.transaction, false)">
<f7-icon f7="trash"></f7-icon>
@@ -260,7 +262,7 @@
<div class="statistics-chart-header display-flex full-line justify-content-space-between">
<div></div>
<div class="align-self-flex-end">
<span style="margin-right: 4px;">{{ tt('Time Granularity') }}</span>
<span style="margin-inline-end: 4px;">{{ tt('Time Granularity') }}</span>
<f7-link :class="{ 'disabled': loading }" href="#" popover-open=".chart-data-date-aggregation-type-popover-menu">{{ chartDataDateAggregationTypeDisplayName }}</f7-link>
</div>
</div>
@@ -352,6 +354,7 @@ import { useAccountsStore } from '@/stores/account.ts';
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
import { useTransactionsStore } from '@/stores/transaction.ts';
import { TextDirection } from '@/core/text.ts';
import { type TimeRangeAndDateType, DateRange, DateRangeScene } from '@/core/datetime.ts';
import { AccountType } from '@/core/account.ts';
import { TransactionType } from '@/core/transaction.ts';
@@ -386,7 +389,14 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt, getAllDateRanges, formatUnixTimeToLongDateTime, formatNumberToLocalizedNumerals } = useI18n();
const {
tt,
getCurrentLanguageTextDirection,
getAllDateRanges,
formatUnixTimeToLongDateTime,
formatNumberToLocalizedNumerals
} = useI18n();
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
const {
@@ -440,6 +450,7 @@ const virtualDataItems = ref<ReconciliationStatementVirtualListData>({
topPosition: 0
});
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const validQuery = computed(() => currentAccount.value && currentAccount.value.type === AccountType.SingleAccount.type);
const allAvailableDateRanges = computed(() => getAllDateRanges(DateRangeScene.Normal, true, !!accountsStore.getAccountStatementDate(accountId.value)));
const displayStartTime = computed<string>(() => formatUnixTimeToLongDateTime(startTime.value));
@@ -708,11 +719,11 @@ init();
}
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date > .item-content {
padding-left: 0 !important;
padding-inline-start: 0 !important;
}
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date > .item-content > .item-inner {
padding-left: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
padding-inline-start: calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-left));
}
.list.reconciliation-statement-list li.reconciliation-statement-transaction-date > .item-content > .item-inner:after {
@@ -725,7 +736,7 @@ init();
}
.list.reconciliation-statement-list li.transaction-info .account-balance {
margin-left: 4px;
margin-inline-start: 4px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
+12 -5
View File
@@ -48,15 +48,19 @@
</f7-badge>
</ItemIcon>
</template>
<f7-swipeout-actions left v-if="sortable">
<f7-swipeout-button :color="category.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
:right="textDirection === TextDirection.RTL"
v-if="sortable">
<f7-swipeout-button :color="category.hidden ? 'blue' : 'gray'" class="padding-horizontal"
overswipe close @click="hide(category, !category.hidden)">
<f7-icon :f7="category.hidden ? 'eye' : 'eye_slash'"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
<f7-swipeout-actions right v-if="!sortable">
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR"
v-if="!sortable">
<f7-swipeout-button color="orange" close :text="tt('Edit')" @click="edit(category)"></f7-swipeout-button>
<f7-swipeout-button color="red" class="padding-left padding-right" @click="remove(category, false)">
<f7-swipeout-button color="red" class="padding-horizontal" @click="remove(category, false)">
<f7-icon f7="trash"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
@@ -96,6 +100,7 @@ import { useCategoryListPageBase } from '@/views/base/categories/CategoryListPag
import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
import { TextDirection } from '@/core/text.ts';
import { CategoryType } from '@/core/category.ts';
import type { TransactionCategory } from '@/models/transaction_category.ts';
@@ -110,7 +115,7 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt } = useI18n();
const { tt, getCurrentLanguageTextDirection } = useI18n();
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
const { loading, primaryCategoryId, currentPrimaryCategory } = useCategoryListPageBase();
@@ -127,6 +132,8 @@ const showDeleteActionSheet = ref<boolean>(false);
const displayOrderModified = ref<boolean>(false);
const displayOrderSaving = ref<boolean>(false);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const categories = computed<TransactionCategory[]>(() => {
if (!primaryCategoryId.value || primaryCategoryId.value === '' || primaryCategoryId.value === '0') {
if (!transactionCategoriesStore.allTransactionCategories || !transactionCategoriesStore.allTransactionCategories[categoryType.value]) {
+1 -1
View File
@@ -21,7 +21,7 @@
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
</template>
<f7-accordion-content v-if="category.subCategories.length" class="padding-left">
<f7-accordion-content v-if="category.subCategories.length" class="padding-inline-start">
<f7-list>
<f7-list-item :title="subCategory.name"
:key="subIdx"
+8 -3
View File
@@ -62,17 +62,19 @@
@swipeout:closed="onExchangeRateSwipeoutClosed()">
<template #title>
<div class="no-padding no-margin">
<span style="margin-right: 5px">{{ exchangeRate.currencyDisplayName }}</span>
<span style="margin-inline-end: 5px">{{ exchangeRate.currencyDisplayName }}</span>
<small class="smaller">{{ exchangeRate.currencyCode }}</small>
</div>
</template>
<f7-swipeout-actions right v-if="exchangeRate.currencyCode !== baseCurrency || (exchangeRate.currencyCode !== defaultCurrency && isUserCustomExchangeRates)">
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR"
v-if="exchangeRate.currencyCode !== baseCurrency || (exchangeRate.currencyCode !== defaultCurrency && isUserCustomExchangeRates)">
<f7-swipeout-button color="primary" close
:text="tt('Set as Base')"
:class="{ 'disabled': exchangeRate.currencyCode === baseCurrency }"
@click="setAsBaseline(exchangeRate.currencyCode, getFinalConvertedAmount(exchangeRate, false)); settingBaseLine = true"
v-if="settingBaseLine || exchangeRate.currencyCode !== baseCurrency"></f7-swipeout-button>
<f7-swipeout-button color="red" class="padding-left padding-right"
<f7-swipeout-button color="red" class="padding-horizontal"
@click="remove(exchangeRate, false)"
v-if="exchangeRate.currencyCode !== defaultCurrency && isUserCustomExchangeRates">
<f7-icon f7="trash"></f7-icon>
@@ -134,6 +136,7 @@ import { useExchangeRatesPageBase } from '@/views/base/ExchangeRatesPageBase.ts'
import { useExchangeRatesStore } from '@/stores/exchangeRates.ts';
import { TextDirection } from '@/core/text.ts';
import { NumeralSystem } from '@/core/numeral.ts';
import { TRANSACTION_MIN_AMOUNT, TRANSACTION_MAX_AMOUNT } from '@/consts/transaction.ts';
@@ -149,6 +152,7 @@ const props = defineProps<{
const {
tt,
getCurrentLanguageTextDirection,
getCurrentNumeralSystemType,
getCurrencyName,
formatAmountToLocalizedNumerals,
@@ -180,6 +184,7 @@ const showBaseAmountSheet = ref<boolean>(false);
const customExchangeRateToDelete = ref<LocalizedLatestExchangeRate | null>(null);
const showDeleteActionSheet = ref<boolean>(false);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const displayBaseAmount = computed<string>(() => formatAmountToLocalizedNumerals(baseAmount.value, baseCurrency.value));
const baseAmountFontSizeClass = computed<string>(() => {
if (baseAmount.value >= 100000000 || baseAmount.value <= -100000000) {
@@ -83,7 +83,7 @@
</template>
<template #root>
<ul class="padding-left"
<ul class="padding-inline-start"
v-if="account.type === AccountType.MultiSubAccounts.type && ((showHidden && accountCategory.allSubAccounts[account.id]) || accountCategory.allVisibleSubAccountCounts[account.id])">
<f7-list-item checkbox
:title="subAccount.name"
@@ -30,7 +30,7 @@
v-for="categorizedItems in ALL_APPLICATION_CLOUD_SETTINGS"
@change="updateSettingsSelected(categorizedItems, $event.target.checked)">
<template #root>
<ul class="padding-left">
<ul class="padding-inline-start">
<f7-list-item checkbox
:disabled="loading || enabling || disabling"
:title="tt(settingItem.settingName)"
@@ -32,7 +32,7 @@
<f7-icon f7="app_fill"></f7-icon>
</template>
<template #root>
<ul class="padding-left">
<ul class="padding-inline-start">
<f7-list-item checkbox class="disabled" title="Sub Category Name"
:key="subItemIdx" v-for="subItemIdx in [ 1, 2, 3 ]">
<template #media>
@@ -91,7 +91,7 @@
</template>
<template #root>
<ul class="padding-left"
<ul class="padding-inline-start"
v-if="(showHidden && categoryType.allSubCategories[category.id]) || categoryType.allVisibleSubCategoryCounts[category.id]">
<f7-list-item checkbox
:title="subCategory.name"
@@ -93,7 +93,10 @@
<div class="display-flex justify-content-space-between">
<div class="fontsize-minimum">A</div>
<div class="fontsize-maximum">A</div>
<div class="fontsize-default" :style="`left: calc(${100 / FontSize.MaximumFontSize.type}% - 6px)`">{{ tt('Default') }}</div>
<div class="fontsize-default"
:style="textDirection === TextDirection.LTR ? `left: calc(${100 / FontSize.MaximumFontSize.type}% - 6px)` : `right: calc(${100 / FontSize.MaximumFontSize.type}% - 6px)`">
{{ tt('Default') }}
</div>
</div>
<f7-range
:min="FontSize.MinimumFontSize.type"
@@ -120,6 +123,7 @@ import { useI18n } from '@/locales/helpers.ts';
import { useSettingsStore } from '@/stores/setting.ts';
import { TextDirection } from '@/core/text.ts';
import { FontSize } from '@/core/font.ts';
import { getLocalDatetimeFromUnixTime, getCurrentUnixTime, getDay, getDayOfWeekName } from '@/lib/datetime.ts';
import { setAppFontSize, getFontSizePreviewClassName } from '@/lib/ui/mobile.ts';
@@ -128,13 +132,21 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt, getWeekdayShortName, formatUnixTimeToLongYearMonth, formatUnixTimeToShortTime, formatAmountToLocalizedNumeralsWithCurrency } = useI18n();
const {
tt,
getCurrentLanguageTextDirection,
getWeekdayShortName,
formatUnixTimeToLongYearMonth,
formatUnixTimeToShortTime,
formatAmountToLocalizedNumeralsWithCurrency
} = useI18n();
const settingsStore = useSettingsStore();
const currentUnixTime = ref<number>(getCurrentUnixTime());
const fontSize = ref<number>(settingsStore.appSettings.fontSize);
const textDirection = computed<string>(() => getCurrentLanguageTextDirection());
const fontSizePreviewClassName = computed<string>(() => getFontSizePreviewClassName(fontSize.value));
const currentLongYearMonth = computed<string>(() => formatUnixTimeToLongYearMonth(currentUnixTime.value));
const currentDayOfMonth = computed<number>(() => getDay(getLocalDatetimeFromUnixTime(currentUnixTime.value)));
@@ -50,8 +50,8 @@
<f7-card v-if="analysisType === StatisticsAnalysisType.CategoricalAnalysis && query.categoricalChartType === CategoricalChartType.Pie.type">
<f7-card-header class="no-border display-block">
<div class="statistics-chart-header full-line text-align-right">
<span style="margin-right: 4px;">{{ tt('Sort by') }}</span>
<div :class="{ 'statistics-chart-header': true, 'full-line': true, 'text-align-right': textDirection === TextDirection.LTR, 'text-align-left': textDirection === TextDirection.RTL}">
<span style="margin-inline-end: 4px;">{{ tt('Sort by') }}</span>
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
</div>
</f7-card-header>
@@ -104,7 +104,7 @@
{{ totalAmountName }}
</div>
<div class="align-self-flex-end">
<span style="margin-right: 4px;">{{ tt('Sort by') }}</span>
<span style="margin-inline-end: 4px;">{{ tt('Sort by') }}</span>
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
</div>
</div>
@@ -196,7 +196,7 @@
<div class="statistics-chart-header display-flex full-line justify-content-space-between">
<div></div>
<div class="align-self-flex-end">
<span style="margin-right: 4px;">{{ tt('Sort by') }}</span>
<span style="margin-inline-end: 4px;">{{ tt('Sort by') }}</span>
<f7-link href="#" popover-open=".sorting-type-popover-menu">{{ querySortingTypeName }}</f7-link>
</div>
</div>
@@ -239,13 +239,13 @@
<f7-toolbar tabbar bottom class="toolbar-item-auto-size">
<f7-link :class="{ 'disabled': reloading || !canShiftDateRange }" @click="shiftDateRange(-1)">
<f7-icon f7="arrow_left_square"></f7-icon>
<f7-icon class="icon-with-direction" f7="arrow_left_square"></f7-icon>
</f7-link>
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': reloading || query.chartDataType === ChartDataType.AccountTotalAssets.type || query.chartDataType === ChartDataType.AccountTotalLiabilities.type }" popover-open=".date-popover-menu">
<span :class="{ 'tabbar-item-changed': isQueryDateRangeChanged }">{{ queryDateRangeName }}</span>
</f7-link>
<f7-link :class="{ 'disabled': reloading || !canShiftDateRange }" @click="shiftDateRange(1)">
<f7-icon f7="arrow_right_square"></f7-icon>
<f7-icon class="icon-with-direction" f7="arrow_right_square"></f7-icon>
</f7-link>
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': reloading }" popover-open=".date-aggregation-popover-menu"
v-if="analysisType === StatisticsAnalysisType.TrendAnalysis">
@@ -343,6 +343,7 @@ import { useTransactionCategoriesStore } from '@/stores/transactionCategory.ts';
import { useStatisticsStore } from '@/stores/statistics.ts';
import type { TypeAndDisplayName } from '@/core/base.ts';
import { TextDirection } from '@/core/text.ts';
import { type TimeRangeAndDateType, DateRangeScene, DateRange } from '@/core/datetime.ts';
import {
StatisticsAnalysisType,
@@ -367,7 +368,13 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt, getAllCategoricalChartTypes, formatPercentToLocalizedNumerals } = useI18n();
const {
tt,
getCurrentLanguageTextDirection,
getAllCategoricalChartTypes,
formatPercentToLocalizedNumerals
} = useI18n();
const { showPrompt, showToast, routeBackOnError } = useI18nUIComponents();
const {
@@ -414,6 +421,8 @@ const showCustomDateRangeSheet = ref<boolean>(false);
const showCustomMonthRangeSheet = ref<boolean>(false);
const showMoreActionSheet = ref<boolean>(false);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const allChartTypes = computed<TypeAndDisplayName[]>(() => {
if (analysisType.value === StatisticsAnalysisType.CategoricalAnalysis) {
return getAllCategoricalChartTypes();
+18 -12
View File
@@ -17,7 +17,7 @@
</template>
<template #title>
<div class="display-flex">
<div class="transaction-tag-list-item-content list-item-valign-middle padding-left-half">Tag Name</div>
<div class="transaction-tag-list-item-content list-item-valign-middle padding-inline-start-half">Tag Name</div>
</div>
</template>
</f7-list-item>
@@ -46,11 +46,11 @@
</template>
<template #title>
<div class="display-flex">
<div class="transaction-tag-list-item-content list-item-valign-middle padding-left-half"
<div class="transaction-tag-list-item-content list-item-valign-middle padding-inline-start-half"
v-if="editingTag.id !== tag.id">
{{ tag.name }}
</div>
<f7-input class="list-title-input padding-left-half"
<f7-input class="list-title-input padding-inline-start-half"
type="text"
:placeholder="tt('Tag Title')"
v-else-if="editingTag.id === tag.id"
@@ -67,7 +67,7 @@
v-if="editingTag.id === tag.id"
@click="save(editingTag)">
</f7-button>
<f7-button class="no-padding margin-left-half"
<f7-button class="no-padding margin-inline-start-half"
raised fill
icon-f7="xmark"
color="gray"
@@ -75,15 +75,19 @@
@click="cancelSave(editingTag)">
</f7-button>
</template>
<f7-swipeout-actions left v-if="sortable && editingTag.id !== tag.id">
<f7-swipeout-button :color="tag.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
:right="textDirection === TextDirection.RTL"
v-if="sortable && editingTag.id !== tag.id">
<f7-swipeout-button :color="tag.hidden ? 'blue' : 'gray'" class="padding-horizontal"
overswipe close @click="hide(tag, !tag.hidden)">
<f7-icon :f7="tag.hidden ? 'eye' : 'eye_slash'"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
<f7-swipeout-actions right v-if="!sortable && editingTag.id !== tag.id">
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR"
v-if="!sortable && editingTag.id !== tag.id">
<f7-swipeout-button color="orange" close :text="tt('Edit')" @click="edit(tag)"></f7-swipeout-button>
<f7-swipeout-button color="red" class="padding-left padding-right" @click="remove(tag, false)">
<f7-swipeout-button color="red" class="padding-horizontal" @click="remove(tag, false)">
<f7-icon f7="trash"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
@@ -95,7 +99,7 @@
</template>
<template #title>
<div class="display-flex">
<f7-input class="list-title-input padding-left-half"
<f7-input class="list-title-input padding-inline-start-half"
type="text"
:placeholder="tt('Tag Title')"
v-model:value="newTag.name"
@@ -110,7 +114,7 @@
color="blue"
@click="save(newTag)">
</f7-button>
<f7-button class="no-padding margin-left-half"
<f7-button class="no-padding margin-inline-start-half"
raised fill
icon-f7="xmark"
color="gray"
@@ -152,6 +156,7 @@ import { useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from
import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
import { TextDirection } from '@/core/text.ts';
import { TransactionTag } from '@/models/transaction_tag.ts';
import {
@@ -164,7 +169,7 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt } = useI18n();
const { tt, getCurrentLanguageTextDirection } = useI18n();
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
const transactionTagsStore = useTransactionTagsStore();
@@ -181,6 +186,7 @@ const showDeleteActionSheet = ref<boolean>(false);
const displayOrderModified = ref<boolean>(false);
const displayOrderSaving = ref<boolean>(false);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const tags = computed<TransactionTag[]>(() => transactionTagsStore.allTransactionTags);
const firstShowingId = computed<string | null>(() => getFirstShowingId(tags.value, showHidden.value));
const lastShowingId = computed<string | null>(() => getLastShowingId(tags.value, showHidden.value));
@@ -413,7 +419,7 @@ init();
<style>
.tag-item-list.list .item-media + .item-inner {
margin-left: 5px;
margin-inline-start: 5px;
}
.transaction-tag-list-item-content {
+11 -5
View File
@@ -46,15 +46,19 @@
</f7-badge>
</f7-icon>
</template>
<f7-swipeout-actions left v-if="sortable">
<f7-swipeout-button :color="template.hidden ? 'blue' : 'gray'" class="padding-left padding-right"
<f7-swipeout-actions :left="textDirection === TextDirection.LTR"
:right="textDirection === TextDirection.RTL"
v-if="sortable">
<f7-swipeout-button :color="template.hidden ? 'blue' : 'gray'" class="padding-horizontal"
overswipe close @click="hide(template, !template.hidden)">
<f7-icon :f7="template.hidden ? 'eye' : 'eye_slash'"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
<f7-swipeout-actions right v-if="!sortable">
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR"
v-if="!sortable">
<f7-swipeout-button color="orange" close :text="tt('Edit')" @click="edit(template)"></f7-swipeout-button>
<f7-swipeout-button color="red" class="padding-left padding-right" @click="remove(template, false)">
<f7-swipeout-button color="red" class="padding-horizontal" @click="remove(template, false)">
<f7-icon f7="trash"></f7-icon>
</f7-swipeout-button>
</f7-swipeout-actions>
@@ -93,6 +97,7 @@ import { useI18nUIComponents, showLoading, hideLoading, onSwipeoutDeleted } from
import { useTransactionTemplatesStore } from '@/stores/transactionTemplate.ts';
import { TextDirection } from '@/core/text.ts';
import { TemplateType } from '@/core/template.ts';
import { TransactionTemplate } from '@/models/transaction_template.ts';
@@ -108,7 +113,7 @@ const props = defineProps<{
f7router: Router.Router;
}>();
const { tt } = useI18n();
const { tt, getCurrentLanguageTextDirection } = useI18n();
const { showAlert, showToast, routeBackOnError } = useI18nUIComponents();
const transactionTemplatesStore = useTransactionTemplatesStore();
@@ -124,6 +129,7 @@ const showDeleteActionSheet = ref<boolean>(false);
const displayOrderModified = ref<boolean>(false);
const displayOrderSaving = ref<boolean>(false);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const templates = computed<TransactionTemplate[]>(() => transactionTemplatesStore.allTransactionTemplates[templateType.value] || []);
const firstShowingId = computed<string | null>(() => getFirstShowingId(templates.value, showHidden.value));
const lastShowingId = computed<string | null>(() => getLastShowingId(templates.value, showHidden.value));
+8 -8
View File
@@ -105,7 +105,7 @@
<template #title>
<div class="list-item-custom-title" v-if="hasAvailableExpenseCategories">
<span>{{ getTransactionPrimaryCategoryName(transaction.expenseCategoryId, allCategories[CategoryType.Expense]) }}</span>
<f7-icon class="category-separate-icon" f7="chevron_right"></f7-icon>
<f7-icon class="category-separate-icon icon-with-direction" f7="chevron_right"></f7-icon>
<span>{{ getTransactionSecondaryCategoryName(transaction.expenseCategoryId, allCategories[CategoryType.Expense]) }}</span>
</div>
<div class="list-item-custom-title" v-else-if="!hasAvailableExpenseCategories">
@@ -137,7 +137,7 @@
<template #title>
<div class="list-item-custom-title" v-if="hasAvailableIncomeCategories">
<span>{{ getTransactionPrimaryCategoryName(transaction.incomeCategoryId, allCategories[CategoryType.Income]) }}</span>
<f7-icon class="category-separate-icon" f7="chevron_right"></f7-icon>
<f7-icon class="category-separate-icon icon-with-direction" f7="chevron_right"></f7-icon>
<span>{{ getTransactionSecondaryCategoryName(transaction.incomeCategoryId, allCategories[CategoryType.Income]) }}</span>
</div>
<div class="list-item-custom-title" v-else-if="!hasAvailableIncomeCategories">
@@ -169,7 +169,7 @@
<template #title>
<div class="list-item-custom-title" v-if="hasAvailableTransferCategories">
<span>{{ getTransactionPrimaryCategoryName(transaction.transferCategoryId, allCategories[CategoryType.Transfer]) }}</span>
<f7-icon class="category-separate-icon" f7="chevron_right"></f7-icon>
<f7-icon class="category-separate-icon icon-with-direction" f7="chevron_right"></f7-icon>
<span>{{ getTransactionSecondaryCategoryName(transaction.transferCategoryId, allCategories[CategoryType.Transfer]) }}</span>
</div>
<div class="list-item-custom-title" v-else-if="!hasAvailableTransferCategories">
@@ -1252,8 +1252,8 @@ init();
<style>
.category-separate-icon.icon {
margin-left: 5px;
margin-right: 5px;
margin-inline-start: 5px;
margin-inline-end: 5px;
font-size: var(--ebk-category-separate-icon-font-size);
line-height: 16px;
color: var(--f7-color-gray-tint);
@@ -1292,19 +1292,19 @@ init();
}
.transaction-edit-timezone-name {
padding-left: 4px;
padding-inline-start: 4px;
}
.transaction-edit-tag {
--f7-chip-bg-color: var(--ebk-transaction-tag-chip-bg-color);
margin-right: 4px;
margin-inline-end: 4px;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
.chip.transaction-edit-tag .chip-media+.chip-label {
margin-left: 0;
margin-inline-start: 0;
}
.chip.transaction-edit-tag .chip-media i.icon {
+31 -17
View File
@@ -47,13 +47,13 @@
<f7-toolbar tabbar bottom class="toolbar-item-auto-size transaction-list-toolbar">
<f7-link :class="{ 'disabled': loading || query.dateType === DateRange.All.type }" @click="shiftDateRange(query.minTime, query.maxTime, -1)">
<f7-icon f7="arrow_left_square"></f7-icon>
<f7-icon class="icon-with-direction" f7="arrow_left_square"></f7-icon>
</f7-link>
<f7-link :class="{ 'tabbar-text-with-ellipsis': true, 'disabled': loading }" popover-open=".date-popover-menu">
<span :class="{ 'tabbar-item-changed': query.dateType !== DateRange.All.type }">{{ queryDateRangeName }}</span>
</f7-link>
<f7-link :class="{ 'disabled': loading || query.dateType === DateRange.All.type }" @click="shiftDateRange(query.minTime, query.maxTime, 1)">
<f7-icon f7="arrow_right_square"></f7-icon>
<f7-icon class="icon-with-direction" f7="arrow_right_square"></f7-icon>
</f7-link>
<f7-link class="tabbar-text-with-ellipsis" popover-open=".category-popover-menu" :class="{ 'disabled': query.type === 1 }">
<span :class="{ 'tabbar-item-changed': query.categoryIds }">{{ queryCategoryName }}</span>
@@ -285,14 +285,15 @@
<span v-if="transaction.utcOffset !== currentTimezoneOffsetMinutes">{{ `(${getDisplayTimezone(transaction)})` }}</span>
<span v-if="transaction.sourceAccount">·</span>
<span v-if="transaction.sourceAccount">{{ transaction.sourceAccount.name }}</span>
<f7-icon f7="arrow_right" class="transaction-account-arrow" v-if="transaction.sourceAccount && transaction.type === TransactionType.Transfer && transaction.destinationAccount && transaction.sourceAccount.id !== transaction.destinationAccount.id"></f7-icon>
<f7-icon class="transaction-account-arrow icon-with-direction" f7="arrow_right" v-if="transaction.sourceAccount && transaction.type === TransactionType.Transfer && transaction.destinationAccount && transaction.sourceAccount.id !== transaction.destinationAccount.id"></f7-icon>
<span v-if="transaction.sourceAccount && transaction.type === TransactionType.Transfer && transaction.destinationAccount && transaction.sourceAccount.id !== transaction.destinationAccount.id">{{ transaction.destinationAccount.name }}</span>
</div>
</div>
</div>
</div>
</template>
<f7-swipeout-actions right>
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR">
<f7-swipeout-button color="primary" close
:text="tt('Duplicate')"
v-if="transaction.type !== TransactionType.ModifyBalance"
@@ -301,7 +302,7 @@
:text="tt('Edit')"
v-if="transaction.editable"
@click="edit(transaction)"></f7-swipeout-button>
<f7-swipeout-button color="red" class="padding-left padding-right"
<f7-swipeout-button color="red" class="padding-horizontal"
v-if="transaction.editable"
@click="remove(transaction, false)">
<f7-icon f7="trash"></f7-icon>
@@ -398,7 +399,7 @@
<ItemIcon icon-type="category" :icon-id="category.icon" :color="category.color"></ItemIcon>
</template>
<f7-accordion-content>
<f7-list dividers class="padding-left">
<f7-list dividers class="padding-inline-start">
<f7-list-item :class="{ 'list-item-selected': query.categoryIds === category.id, 'item-in-multiple-selection': queryAllFilterCategoryIdsCount > 1 && queryAllFilterCategoryIds[category.id] }"
:title="tt('All')" @click="changeCategoryFilter(category.id)">
<template #media>
@@ -520,7 +521,7 @@
v-for="filterType in AmountFilterType.values()"
@click="changeAmountFilter(filterType.type)">
<template #after>
<span class="margin-right-half" v-if="query.amountFilter && query.amountFilter.startsWith(`${filterType.type}:`)">{{ queryAmount }}</span>
<span class="margin-inline-end-half" v-if="query.amountFilter && query.amountFilter.startsWith(`${filterType.type}:`)">{{ queryAmount }}</span>
<f7-icon class="list-item-checked-icon" f7="checkmark_alt" v-if="query.amountFilter && query.amountFilter.startsWith(`${filterType.type}:`)"></f7-icon>
</template>
</f7-list-item>
@@ -617,6 +618,7 @@ import { useTransactionTagsStore } from '@/stores/transactionTag.ts';
import { type TransactionMonthList, useTransactionsStore } from '@/stores/transaction.ts';
import type { TypeAndDisplayName } from '@/core/base.ts';
import { TextDirection } from '@/core/text.ts';
import {
type TimeRangeAndDateType,
DateRangeScene,
@@ -662,6 +664,7 @@ const props = defineProps<{
const {
tt,
getCurrentLanguageTextDirection,
getAllShortWeekdayNames,
getAllTransactionTagFilterTypes,
getWeekdayShortName
@@ -739,6 +742,7 @@ const showCustomDateRangeSheet = ref<boolean>(false);
const showCustomMonthSheet = ref<boolean>(false);
const showDeleteActionSheet = ref<boolean>(false);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const isDarkMode = computed<boolean>(() => environmentsStore.framework7DarkMode || false);
const dayNames = computed<string[]>(() => arrangeArrayWithNewStartIndex(getAllShortWeekdayNames(), firstDayOfWeek.value));
@@ -1511,7 +1515,7 @@ init();
<style>
.transaction-list-toolbar .toolbar-inner {
padding-right: 8px;
padding-inline-end: 8px;
}
.list.transaction-amount-list .transaction-amount-statistics {
@@ -1520,17 +1524,17 @@ init();
}
.list.transaction-amount-list .transaction-amount-statistics > span {
margin-left: 8px;
margin-inline-start: 8px;
font-weight: normal;
}
.list.transaction-info-list li.transaction-info .item-media + .item-inner {
margin-left: 0;
margin-inline-start: 0;
}
.list.transaction-info-list li.transaction-info .actual-item-inner {
width: 100%;
margin-left: 10px;
margin-inline-start: 10px;
overflow: hidden;
}
@@ -1540,7 +1544,7 @@ init();
.list.transaction-info-list li.transaction-info .transaction-date {
width: var(--ebk-transaction-date-width);
margin-right: 6px;
margin-inline-end: 6px;
}
.list.transaction-info-list li.transaction-info .transaction-day {
@@ -1550,6 +1554,10 @@ init();
text-align: left;
}
html[dir="rtl"] .list.transaction-info-list li.transaction-info .transaction-day {
text-align: right;
}
.list.transaction-info-list li.transaction-info .transaction-day-of-week {
opacity: 0.6;
font-size: var(--ebk-transaction-day-of-week-font-size);
@@ -1569,14 +1577,14 @@ init();
--f7-chip-height: var(--ebk-transaction-tag-chip-height);
--f7-chip-text-color: var(--f7-list-item-footer-text-color);
--f7-chip-bg-color: var(--ebk-transaction-tag-chip-bg-color);
margin-right: 4px;
margin-inline-end: 4px;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
.list.transaction-info-list li.transaction-info .chip.transaction-tag .chip-media+.chip-label {
margin-left: 0;
margin-inline-start: 0;
}
.list.transaction-info-list li.transaction-info .transaction-footer {
@@ -1588,15 +1596,21 @@ init();
}
.list.transaction-info-list li.transaction-info .transaction-footer > span {
margin-right: 4px;
unicode-bidi: isolate;
margin-inline-end: 4px;
}
.list.transaction-info-list li.transaction-info .transaction-footer .transaction-account-arrow {
font-size: var(--ebk-transaction-account-arrow-font-size);
margin-right: 4px;
margin-inline-end: 4px;
margin-top: var(--ebk-transaction-account-arrow-margin-top);
}
html[dir="rtl"] .list.transaction-info-list li.transaction-info .transaction-footer .transaction-account-arrow {
margin-inline-end: 0;
margin-inline-start: 4px;
}
.list.transaction-info-list li.transaction-info .transaction-amount {
color: var(--f7-list-item-after-text-color);
overflow: hidden;
@@ -1613,7 +1627,7 @@ init();
}
.more-popover-menu .transaction-tag-name {
padding-right: 4px;
padding-inline-end: 4px;
font-size: var(--f7-list-item-title-font-size);
}
@@ -184,6 +184,6 @@ reloadUserDataStatistics();
<style>
.export-file-type-list.list > ul > li > .item-content {
padding-left: 0;
padding-inline-start: 0;
}
</style>
+7 -2
View File
@@ -34,7 +34,9 @@
<template #after>
<small>{{ session.lastSeenDateTime }}</small>
</template>
<f7-swipeout-actions right v-if="!session.isCurrent">
<f7-swipeout-actions :left="textDirection === TextDirection.RTL"
:right="textDirection === TextDirection.LTR"
v-if="!session.isCurrent">
<f7-swipeout-button color="red" :text="tt('Log Out')" @click="revoke(session)"></f7-swipeout-button>
</f7-swipeout-actions>
</f7-list-item>
@@ -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<TokenInfoResponse[]>([]);
const loading = ref<boolean>(true);
const loadingError = ref<unknown | null>(null);
const textDirection = computed<TextDirection>(() => getCurrentLanguageTextDirection());
const sessions = computed<MobilePageSessionInfo[]>(() => {
const sessions: MobilePageSessionInfo[] = [];
+16 -2
View File
@@ -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();
+66 -2
View File
@@ -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<string, string> = {};
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 => {