Compare commits

..

No commits in common. "e9551d6915c047931183ba90aae3fc967e9e9669" and "a97963001ad376a90b6afd322c916022a4f57594" have entirely different histories.

5 changed files with 85 additions and 128 deletions

View file

@ -13,31 +13,3 @@ You can debug on the Safari on iOS only if you have mac (and run macOS). The cer
## Hero Animation won't work (after hot reload) ## Hero Animation won't work (after hot reload)
That's a known issue. Hot reload won't refresh the module sets the hero cache. Refresh the whole page and it should work. That's a known issue. Hot reload won't refresh the module sets the hero cache. Refresh the whole page and it should work.
## The components don't react to the change as I setting the store, until the page reloaded
The `WritableAtom<unknwon>.set` might do an equals check. You must set a different object to ensure the atom sending a notify.
The code below may not notify the change:
```ts
export function updateAcctInf(idx: number) {
const o = $accounts.get();
// ...
o[idx].inf = inf;
$accounts.set(o);
}
```
Instead, set a new object:
```ts
export function updateAcctInf(idx: number) {
const o = $accounts.get();
// ...
o[idx] = Object.assign({}, o[idx], { inf });
$accounts.set(Array.from(o));
}
```
Ja, the code is weird, but that's the best we know. Anyway, you need new object on the path of your changed value.

View file

@ -2,9 +2,8 @@ import { Route, Router } from "@solidjs/router";
import { ThemeProvider } from "@suid/material"; import { ThemeProvider } from "@suid/material";
import { import {
Component, Component,
createEffect,
createMemo,
createRenderEffect, createRenderEffect,
createSignal,
ErrorBoundary, ErrorBoundary,
lazy, lazy,
onCleanup, onCleanup,
@ -13,8 +12,9 @@ import { useRootTheme } from "./material/mui.js";
import { import {
Provider as ClientProvider, Provider as ClientProvider,
createMastoClientFor, createMastoClientFor,
type Session,
} from "./masto/clients.js"; } from "./masto/clients.js";
import { $accounts, updateAcctInf } from "./accounts/stores.js"; import { $accounts } from "./accounts/stores.js";
import { useStore } from "@nanostores/solid"; import { useStore } from "@nanostores/solid";
import { DateFnScope, useLanguage } from "./platform/i18n.jsx"; import { DateFnScope, useLanguage } from "./platform/i18n.jsx";
@ -28,7 +28,6 @@ const TootBottomSheet = lazy(() => import("./timelines/TootBottomSheet.js"));
const MotionSettings = lazy(() => import("./settings/Motions.js")); const MotionSettings = lazy(() => import("./settings/Motions.js"));
const LanguageSettings = lazy(() => import("./settings/Language.js")); const LanguageSettings = lazy(() => import("./settings/Language.js"));
const RegionSettings = lazy(() => import("./settings/Region.jsx")); const RegionSettings = lazy(() => import("./settings/Region.jsx"));
const UnexpectedError = lazy(() => import("./UnexpectedError.js"));
const Routing: Component = () => { const Routing: Component = () => {
return ( return (
@ -57,30 +56,14 @@ const Routing: Component = () => {
const App: Component = () => { const App: Component = () => {
const theme = useRootTheme(); const theme = useRootTheme();
const accts = useStore($accounts); const accts = useStore($accounts);
const clientStore = createSignal<Session[]>([]);
const lang = useLanguage(); const lang = useLanguage();
const clients = createMemo(() => { createRenderEffect(() => {
return accts().map((x) => ({ const [, setClients] = clientStore;
account: x, setClients(
client: createMastoClientFor(x), accts().map((x) => ({ account: x, client: createMastoClientFor(x) })),
}));
});
createEffect(() => {
const neededUpdates = accts()
.map((x, i) => [i, x] as const)
.filter(([, x]) => !x.inf);
if (neededUpdates.length > 0) {
// FIXME: we might need some kind of concurrent control
Promise.all(neededUpdates.map(([i]) => updateAcctInf(i))).then(
(x) => {
console.info("acct info updated for %d acct(s)", x.length);
},
(reason) => {
console.error("acct info update is fail", reason);
},
); );
}
}); });
createRenderEffect(() => { createRenderEffect(() => {
@ -93,6 +76,8 @@ const App: Component = () => {
root.removeAttribute("lang"); root.removeAttribute("lang");
}); });
const UnexpectedError = lazy(() => import("./UnexpectedError.js"));
return ( return (
<ErrorBoundary <ErrorBoundary
fallback={(err, reset) => { fallback={(err, reset) => {
@ -102,7 +87,7 @@ const App: Component = () => {
> >
<ThemeProvider theme={theme()}> <ThemeProvider theme={theme()}>
<DateFnScope> <DateFnScope>
<ClientProvider value={clients}> <ClientProvider value={clientStore}>
<Routing /> <Routing />
</ClientProvider> </ClientProvider>
</DateFnScope> </DateFnScope>

View file

@ -82,8 +82,8 @@ export async function updateAcctInf(idx: number) {
const o = $accounts.get(); const o = $accounts.get();
const client = createMastoClientFor(o[idx]); const client = createMastoClientFor(o[idx]);
const inf = await client.v1.accounts.verifyCredentials(); const inf = await client.v1.accounts.verifyCredentials();
o[idx] = Object.assign({}, o[idx], { inf }); o[idx].inf = inf;
$accounts.set(Array.from(o)); $accounts.set(o);
return inf; return inf;
} }

View file

@ -49,12 +49,12 @@ export type Session = {
client: mastodon.rest.Client; client: mastodon.rest.Client;
}; };
const Context = /* @__PURE__ */ createContext<Accessor<readonly Readonly<Session>[]>>(); const Context = /* @__PURE__ */ createContext<Signal<Session[]>>();
export const Provider = Context.Provider; export const Provider = Context.Provider;
export function useSessions() { export function useSessions() {
const sessions = useSessionsRaw(); const [sessions] = useSessionsRw();
const navigate = useNavigate(); const navigate = useNavigate();
const location = useLocation(); const location = useLocation();
@ -69,7 +69,7 @@ export function useSessions() {
return sessions; return sessions;
} }
function useSessionsRaw() { function useSessionsRw() {
const store = useContext(Context); const store = useContext(Context);
if (!store) { if (!store) {
throw new TypeError("sessions are not provided"); throw new TypeError("sessions are not provided");

View file

@ -118,12 +118,12 @@ const BottomSheet: ParentComponent<BottomSheetProps> = (props) => {
animation = element.animate( animation = element.animate(
{ {
top: [`${rect.top}px`, `${rect.top}px`], top: [rect.top, rect.top],
left: reserve left: reserve
? [`${rect.left}px`, `${window.innerWidth}px`] ? [`${rect.left}px`, `${window.innerWidth}px`]
: [`${window.innerWidth}px`, `${rect.left}px`], : [`${window.innerWidth}px`, `${rect.left}px`],
width: [`${rect.width}px`, `${rect.width}px`], width: [rect.width, rect.width],
height: [`${rect.height}px`, `${rect.height}px`], height: [rect.height, rect.height],
}, },
{ easing, duration }, { easing, duration },
); );
@ -151,12 +151,12 @@ const BottomSheet: ParentComponent<BottomSheetProps> = (props) => {
animation = element.animate( animation = element.animate(
{ {
left: [`${rect.left}px`, `${rect.left}px`], left: [rect.left, rect.left],
top: reserve top: reserve
? [`${rect.top}px`, `${window.innerHeight}px`] ? [`${rect.top}px`, `${window.innerHeight}px`]
: [`${window.innerHeight}px`, `${rect.top}px`], : [`${window.innerHeight}px`, `${rect.top}px`],
width: [`${rect.width}px`, `${rect.width}px`], width: [rect.width, rect.width],
height: [`${rect.height}px`, `${rect.height}px`], height: [rect.height, rect.height],
}, },
{ easing, duration }, { easing, duration },
); );