mirror of
https://github.com/aljazceru/mutiny-web.git
synced 2026-02-20 21:54:23 +01:00
clean up activity syncing
This commit is contained in:
committed by
Tony Giorgio
parent
09a1e4d009
commit
b2d9208a58
@@ -3,9 +3,9 @@ import {
|
||||
For,
|
||||
Match,
|
||||
Show,
|
||||
Suspense,
|
||||
Switch,
|
||||
createEffect,
|
||||
createResource,
|
||||
createSignal
|
||||
} from "solid-js";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
@@ -13,7 +13,9 @@ import { useI18n } from "~/i18n/context";
|
||||
import { Contact } from "@mutinywallet/mutiny-wasm";
|
||||
import { ActivityItem, HackActivityType } from "./ActivityItem";
|
||||
import { DetailsIdModal } from "./DetailsModal";
|
||||
import { A } from "solid-start";
|
||||
import { LoadingShimmer } from "./BalanceBox";
|
||||
import { createDeepSignal } from "~/utils/deepSignal";
|
||||
|
||||
export const THREE_COLUMNS =
|
||||
"grid grid-cols-[auto,1fr,auto] gap-4 py-2 px-2 border-b border-neutral-800 last:border-b-0";
|
||||
@@ -85,8 +87,10 @@ function UnifiedActivityItem(props: {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function CombinedActivity(props: { limit?: number }) {
|
||||
const [state, actions] = useMegaStore();
|
||||
const [state, _actions] = useMegaStore();
|
||||
const i18n = useI18n();
|
||||
|
||||
const [detailsOpen, setDetailsOpen] = createSignal(false);
|
||||
@@ -107,14 +111,26 @@ export function CombinedActivity(props: { limit?: number }) {
|
||||
setDetailsOpen(true);
|
||||
}
|
||||
|
||||
async function fetchActivity() {
|
||||
return await state.mutiny_wallet?.get_activity();
|
||||
}
|
||||
|
||||
const [activity, { refetch }] = createResource(fetchActivity, {
|
||||
storage: createDeepSignal
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
if (!state.wallet_loading && !state.is_syncing) {
|
||||
actions.syncActivity();
|
||||
// Should re-run after every sync
|
||||
if (!state.is_syncing) {
|
||||
refetch();
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Suspense fallback={<LoadingShimmer />}>
|
||||
<Show
|
||||
when={activity.state === "ready" || activity.state === "refreshing"}
|
||||
fallback={<LoadingShimmer />}
|
||||
>
|
||||
<Show when={detailsId() && detailsKind()}>
|
||||
<DetailsIdModal
|
||||
open={detailsOpen()}
|
||||
@@ -124,7 +140,7 @@ export function CombinedActivity(props: { limit?: number }) {
|
||||
/>
|
||||
</Show>
|
||||
<Switch>
|
||||
<Match when={state.activity.length === 0}>
|
||||
<Match when={activity.latest.length === 0}>
|
||||
<div class="w-full text-center pb-4">
|
||||
<NiceP>
|
||||
{i18n.t("receive_some_sats_to_get_started")}
|
||||
@@ -132,9 +148,9 @@ export function CombinedActivity(props: { limit?: number }) {
|
||||
</div>
|
||||
</Match>
|
||||
<Match
|
||||
when={props.limit && state.activity.length > props.limit}
|
||||
when={props.limit && activity.latest.length > props.limit}
|
||||
>
|
||||
<For each={state.activity.slice(0, props.limit)}>
|
||||
<For each={activity.latest.slice(0, props.limit)}>
|
||||
{(activityItem) => (
|
||||
<UnifiedActivityItem
|
||||
item={activityItem}
|
||||
@@ -143,8 +159,8 @@ export function CombinedActivity(props: { limit?: number }) {
|
||||
)}
|
||||
</For>
|
||||
</Match>
|
||||
<Match when={state.activity.length >= 0}>
|
||||
<For each={state.activity}>
|
||||
<Match when={activity.latest.length >= 0}>
|
||||
<For each={activity.latest}>
|
||||
{(activityItem) => (
|
||||
<UnifiedActivityItem
|
||||
item={activityItem}
|
||||
@@ -154,6 +170,14 @@ export function CombinedActivity(props: { limit?: number }) {
|
||||
</For>
|
||||
</Match>
|
||||
</Switch>
|
||||
</Suspense>
|
||||
<Show when={props.limit && activity.latest.length > 0}>
|
||||
<A
|
||||
href="/activity"
|
||||
class="text-m-red active:text-m-red/80 font-semibold no-underline self-center"
|
||||
>
|
||||
{i18n.t("view_all")}
|
||||
</A>
|
||||
</Show>
|
||||
</Show>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { A } from "solid-start";
|
||||
import { OnboardWarning } from "~/components/OnboardWarning";
|
||||
import { CombinedActivity } from "./Activity";
|
||||
import { useMegaStore } from "~/state/megaStore";
|
||||
import { Match, Show, Switch } from "solid-js";
|
||||
import { Match, Show, Suspense, Switch } from "solid-js";
|
||||
import { ExternalLink } from "./layout/ExternalLink";
|
||||
import { BetaWarningModal } from "~/components/BetaWarningModal";
|
||||
import settings from "~/assets/icons/settings.svg";
|
||||
@@ -74,21 +74,15 @@ export default function App() {
|
||||
<Card title="Activity">
|
||||
<div class="p-1" />
|
||||
<VStack>
|
||||
<Show
|
||||
when={!state.wallet_loading}
|
||||
fallback={<LoadingShimmer />}
|
||||
>
|
||||
<CombinedActivity limit={3} />
|
||||
</Show>
|
||||
<Suspense>
|
||||
<Show
|
||||
when={!state.wallet_loading}
|
||||
fallback={<LoadingShimmer />}
|
||||
>
|
||||
<CombinedActivity limit={3} />
|
||||
</Show>
|
||||
</Suspense>
|
||||
</VStack>
|
||||
<Show when={state.activity && state.activity.length > 0}>
|
||||
<A
|
||||
href="/activity"
|
||||
class="text-m-red active:text-m-red/80 font-semibold no-underline self-center"
|
||||
>
|
||||
{i18n.t("view_all")}
|
||||
</A>
|
||||
</Show>
|
||||
</Card>
|
||||
<p class="self-center text-neutral-500 mt-4 font-normal">
|
||||
Bugs? Feedback?{" "}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { For, Show, createResource } from "solid-js";
|
||||
import { For, Show, Suspense, createResource } from "solid-js";
|
||||
import NavBar from "~/components/NavBar";
|
||||
import {
|
||||
Button,
|
||||
@@ -107,12 +107,14 @@ export default function Activity() {
|
||||
<Card title="Activity">
|
||||
<div class="p-1" />
|
||||
<VStack>
|
||||
<Show
|
||||
when={!state.wallet_loading}
|
||||
fallback={<LoadingShimmer />}
|
||||
>
|
||||
<CombinedActivity />
|
||||
</Show>
|
||||
<Suspense>
|
||||
<Show
|
||||
when={!state.wallet_loading}
|
||||
fallback={<LoadingShimmer />}
|
||||
>
|
||||
<CombinedActivity />
|
||||
</Show>
|
||||
</Suspense>
|
||||
</VStack>
|
||||
</Card>
|
||||
</Tabs.Content>
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
onMount,
|
||||
useContext
|
||||
} from "solid-js";
|
||||
import { createStore, reconcile } from "solid-js/store";
|
||||
import { createStore } from "solid-js/store";
|
||||
import {
|
||||
MutinyWalletSettingStrings,
|
||||
doubleInitDefense,
|
||||
@@ -21,7 +21,6 @@ import { MutinyTagItem } from "~/utils/tags";
|
||||
import { checkBrowserCompatibility } from "~/logic/browserCompatibility";
|
||||
import eify from "~/utils/eify";
|
||||
import { timeout } from "~/utils/timeout";
|
||||
import { ActivityItem } from "~/components/Activity";
|
||||
import { ParsedParams } from "~/logic/waila";
|
||||
|
||||
const MegaStoreContext = createContext<MegaStore>();
|
||||
@@ -51,7 +50,6 @@ export type MegaStore = [
|
||||
has_backed_up: boolean;
|
||||
dismissed_restore_prompt: boolean;
|
||||
wallet_loading: boolean;
|
||||
activity: ActivityItem[];
|
||||
setup_error?: Error;
|
||||
is_pwa: boolean;
|
||||
existing_tab_detected: boolean;
|
||||
@@ -73,7 +71,6 @@ export type MegaStore = [
|
||||
dismissRestorePrompt(): void;
|
||||
setHasBackedUp(): void;
|
||||
listTags(): Promise<MutinyTagItem[]>;
|
||||
syncActivity(): Promise<void>;
|
||||
checkBrowserCompat(): Promise<boolean>;
|
||||
checkForSubscription(justPaid?: boolean): Promise<void>;
|
||||
}
|
||||
@@ -97,7 +94,6 @@ export const Provider: ParentComponent = (props) => {
|
||||
dismissed_restore_prompt:
|
||||
localStorage.getItem("dismissed_restore_prompt") === "true",
|
||||
wallet_loading: true,
|
||||
activity: [] as ActivityItem[],
|
||||
setup_error: undefined as Error | undefined,
|
||||
is_pwa: window.matchMedia("(display-mode: standalone)").matches,
|
||||
existing_tab_detected: false,
|
||||
@@ -287,14 +283,6 @@ export const Provider: ParentComponent = (props) => {
|
||||
setState({ is_syncing: false });
|
||||
}
|
||||
},
|
||||
async syncActivity(): Promise<void> {
|
||||
try {
|
||||
const activity = await state.mutiny_wallet?.get_activity();
|
||||
setState("activity", reconcile(activity, { merge: true }));
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
setScanResult(scan_result: ParsedParams) {
|
||||
setState({ scan_result });
|
||||
},
|
||||
|
||||
21
src/utils/deepSignal.ts
Normal file
21
src/utils/deepSignal.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { Signal } from "solid-js";
|
||||
import { createStore, reconcile, unwrap } from "solid-js/store";
|
||||
|
||||
// All these shenanigans are so we don't get a flicker after every refresh
|
||||
// API may change in the future: https://docs.solidjs.com/references/api-reference/basic-reactivity/createResource
|
||||
export function createDeepSignal<T>(value: T): Signal<T> {
|
||||
const [store, setStore] = createStore({
|
||||
value
|
||||
});
|
||||
return [
|
||||
// eslint-disable-next-line
|
||||
() => store.value,
|
||||
// eslint-disable-next-line
|
||||
(v: T) => {
|
||||
const unwrapped = unwrap(store.value);
|
||||
typeof v === "function" && (v = v(unwrapped));
|
||||
setStore("value", reconcile(v, { merge: true }));
|
||||
return store.value;
|
||||
}
|
||||
] as Signal<T>;
|
||||
}
|
||||
Reference in New Issue
Block a user