clean up activity syncing

This commit is contained in:
Paul Miller
2023-07-12 12:09:44 -05:00
committed by Tony Giorgio
parent 09a1e4d009
commit b2d9208a58
5 changed files with 75 additions and 46 deletions

View File

@@ -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>
);
}

View File

@@ -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?{" "}

View File

@@ -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>

View File

@@ -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
View 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>;
}