3 Commits

Author SHA1 Message Date
56e5ae6629 Update dependency eslint to ^9.31.0
Some checks are pending
continuous-integration/drone/push Build is pending
continuous-integration/drone/pr Build is pending
2025-07-22 00:19:56 +00:00
4443131516 Can download APK from web app
All checks were successful
continuous-integration/drone/push Build is passing
2025-07-21 19:48:32 +02:00
365d7589b1 Force refresh of expenses editor
All checks were successful
continuous-integration/drone/push Build is passing
2025-07-20 19:55:18 +02:00
8 changed files with 74 additions and 975 deletions

View File

@@ -126,6 +126,14 @@ pub struct AppConfig {
/// Redis password /// Redis password
#[clap(long, env, default_value = "secretredis")] #[clap(long, env, default_value = "secretredis")]
redis_password: String, redis_password: String,
/// Application download URL
#[clap(
long,
env,
default_value = "https://gitea.communiquons.org/pierre/MoneyMgr/releases/download/latest/moneymgr_mobile_arm64-v8a.apk"
)]
pub apk_download_url: String,
} }
lazy_static::lazy_static! { lazy_static::lazy_static! {

View File

@@ -70,6 +70,7 @@ impl Default for ServerConstraints {
struct ServerConfig { struct ServerConfig {
auth_disabled: bool, auth_disabled: bool,
oidc_provider_name: &'static str, oidc_provider_name: &'static str,
apk_download_url: &'static str,
accounts_types: &'static [AccountTypeDesc], accounts_types: &'static [AccountTypeDesc],
constraints: ServerConstraints, constraints: ServerConstraints,
} }
@@ -79,6 +80,7 @@ impl Default for ServerConfig {
Self { Self {
auth_disabled: AppConfig::get().is_auth_disabled(), auth_disabled: AppConfig::get().is_auth_disabled(),
oidc_provider_name: AppConfig::get().openid_provider().name, oidc_provider_name: AppConfig::get().openid_provider().name,
apk_download_url: AppConfig::get().apk_download_url.as_str(),
constraints: Default::default(), constraints: Default::default(),
accounts_types: &ACCOUNT_TYPES, accounts_types: &ACCOUNT_TYPES,
} }

View File

@@ -36,8 +36,8 @@ class ScanScreen extends HookConsumerWidget {
restartScan() async { restartScan() async {
try { try {
final val = ref.refresh(_scanDocumentProvider); ref.invalidate(_scanDocumentProvider);
Logger.root.info("Load again startup result: $val"); Logger.root.info("Load again startup");
} catch (e, s) { } catch (e, s) {
Logger.root.shout("Failed to try again startup loading! $e $s"); Logger.root.shout("Failed to try again startup loading! $e $s");
} }

View File

@@ -40,6 +40,15 @@ class ExpenseEditor extends HookConsumerWidget {
final (:pending, :snapshot, :hasError) = useAsyncTask(); final (:pending, :snapshot, :hasError) = useAsyncTask();
// Force refresh of field if required
final previousData = useState<BaseExpenseInfo?>(null);
if (initialData != previousData.value) {
previousData.value = initialData;
labelController.text = initialData?.label ?? "";
costController.text = initialData?.cost.toString() ?? "";
timeController.value = initialData?.time ?? DateTime.now();
}
// Clear cost value // Clear cost value
handleClearCost() { handleClearCost() {
costController.text = ""; costController.text = "";

File diff suppressed because it is too large Load Diff

View File

@@ -36,7 +36,7 @@
"@types/react": "^19.1.8", "@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6", "@types/react-dom": "^19.1.6",
"@vitejs/plugin-react": "^4.6.0", "@vitejs/plugin-react": "^4.6.0",
"eslint": "^9.26.0", "eslint": "^9.31.0",
"eslint-plugin-react-dom": "^1.49.0", "eslint-plugin-react-dom": "^1.49.0",
"eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^00.4.20", "eslint-plugin-react-refresh": "^00.4.20",

View File

@@ -3,6 +3,7 @@ import { APIClient } from "./ApiClient";
export interface ServerConfig { export interface ServerConfig {
auth_disabled: boolean; auth_disabled: boolean;
oidc_provider_name: string; oidc_provider_name: string;
apk_download_url: string;
accounts_types: AccountType[]; accounts_types: AccountType[];
constraints: ServerConstraints; constraints: ServerConstraints;
} }

View File

@@ -1,5 +1,6 @@
import { mdiApi, mdiCash } from "@mdi/js"; import { mdiApi, mdiCash } from "@mdi/js";
import Icon from "@mdi/react"; import Icon from "@mdi/react";
import AndroidIcon from "@mui/icons-material/Android";
import CloudDownloadIcon from "@mui/icons-material/CloudDownload"; import CloudDownloadIcon from "@mui/icons-material/CloudDownload";
import LogoutIcon from "@mui/icons-material/Logout"; import LogoutIcon from "@mui/icons-material/Logout";
import SettingsIcon from "@mui/icons-material/Settings"; import SettingsIcon from "@mui/icons-material/Settings";
@@ -10,6 +11,7 @@ import MenuItem from "@mui/material/MenuItem";
import Toolbar from "@mui/material/Toolbar"; import Toolbar from "@mui/material/Toolbar";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import * as React from "react"; import * as React from "react";
import { ServerApi } from "../api/ServerApi";
import { useAuthInfo } from "./BaseAuthenticatedPage"; import { useAuthInfo } from "./BaseAuthenticatedPage";
import { DarkThemeButton } from "./DarkThemeButtonWidget"; import { DarkThemeButton } from "./DarkThemeButtonWidget";
import { PublicModeButton } from "./PublicModeButtonWidget"; import { PublicModeButton } from "./PublicModeButtonWidget";
@@ -100,6 +102,18 @@ export function MoneyWebAppBar(p: {
</MenuItem> </MenuItem>
</RouterLink> </RouterLink>
{/* APK download */}
<RouterLink to={ServerApi.Config.apk_download_url}>
<MenuItem>
<ListItemIcon>
<AndroidIcon />
</ListItemIcon>
<ListItemText secondary="Scan expenses from your smartphone">
Mobile Application
</ListItemText>
</MenuItem>
</RouterLink>
<Divider /> <Divider />
{/* Sign out */} {/* Sign out */}