mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-20 05:56:53 +00:00
fe05afec19
The Share button becomes the trip's Settings, a round button beside the back pill. The dialog is rebuilt around three areas (People, Sharing, Journal) with a side navigation, a fixed height and 960 px width on wide screens. Journal links one of your journals from the Journey addon to the trip. Every trip member is ticked as a reader by default, each can be raised to editor or left out, and the people a save would let in for the first time are named before it saves. The link can be changed or removed. With a link the trip gets a Journal tab on desktop and phone that shows the Journey addon's own view, live through its sync and trip:journal:changed. Nothing shows with the addon off. members.shareTrip and nav.share are gone with the button that used them.
50 lines
2.3 KiB
TypeScript
50 lines
2.3 KiB
TypeScript
import type { TripJournalLinkMemberRequest, TripJournalLinkResponse } from '@trek/shared';
|
|
import { create } from 'zustand';
|
|
import { tripJournalLinkRepo } from '../repo/tripJournalLinkRepo';
|
|
|
|
/**
|
|
* The journal each trip links, as this person may see it, remembered for the
|
|
* session so the trip's Journal tab and its Settings dialog render the last
|
|
* answer at once. Both read it from here, so the tab appears and goes the moment
|
|
* the dialog links or unlinks, without a second request.
|
|
*/
|
|
interface TripJournalLinkState {
|
|
/** Per trip id, the server's answer. Missing until asked. */
|
|
byTrip: Record<string, TripJournalLinkResponse>;
|
|
refresh: (tripId: number) => Promise<void>;
|
|
link: (tripId: number, journeyId: number, members: TripJournalLinkMemberRequest[]) => Promise<void>;
|
|
setMembers: (tripId: number, members: TripJournalLinkMemberRequest[]) => Promise<void>;
|
|
unlink: (tripId: number) => Promise<void>;
|
|
}
|
|
|
|
/** The answer for a trip someone cannot reach, or with the Journey addon off: no journal. */
|
|
const NONE: TripJournalLinkResponse = { link: null, can_link: false, can_unlink: false, can_edit_members: false };
|
|
|
|
export const useTripJournalLinkStore = create<TripJournalLinkState>((set) => {
|
|
const keep = (tripId: number, answer: TripJournalLinkResponse) =>
|
|
set((s) => ({ byTrip: { ...s.byTrip, [String(tripId)]: answer } }));
|
|
|
|
return {
|
|
byTrip: {},
|
|
|
|
refresh: async (tripId) => {
|
|
try {
|
|
keep(tripId, await tripJournalLinkRepo.get(tripId));
|
|
} catch (err) {
|
|
// 404 is the Journey addon switched off or a trip this person no longer
|
|
// reaches: both a real "no journal". Anything else, offline included, is
|
|
// no answer at all, and the last one stands.
|
|
const status = (err as { response?: { status?: number } })?.response?.status;
|
|
if (status === 404 || status === 403) keep(tripId, NONE);
|
|
}
|
|
},
|
|
|
|
// The writes answer with the link as it now stands, so the tab and the
|
|
// dialog move together; a failure is the caller's to report.
|
|
link: async (tripId, journeyId, members) =>
|
|
keep(tripId, await tripJournalLinkRepo.link(tripId, journeyId, members)),
|
|
setMembers: async (tripId, members) => keep(tripId, await tripJournalLinkRepo.setMembers(tripId, members)),
|
|
unlink: async (tripId) => keep(tripId, await tripJournalLinkRepo.unlink(tripId)),
|
|
};
|
|
});
|