-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathDiaryChannel.tsx
200 lines (184 loc) · 5.89 KB
/
DiaryChannel.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
import React, { useEffect, useState } from 'react';
import _ from 'lodash';
import { Outlet, useLocation, useNavigate, useParams } from 'react-router';
import Layout from '@/components/Layout/Layout';
import {
GROUP_ADMIN,
useAmAdmin,
useChannel,
useRouteGroup,
useVessel,
} from '@/state/groups/groups';
import {
useNotesForDiary,
useDiaryState,
useDiaryDisplayMode,
useDiaryPerms,
} from '@/state/diary';
import {
DiarySetting,
setSetting,
useDiarySettings,
useDiarySortMode,
useSettingsState,
} from '@/state/settings';
import ChannelHeader from '@/channels/ChannelHeader';
import useDismissChannelNotifications from '@/logic/useDismissChannelNotifications';
import { DiaryDisplayMode } from '@/types/diary';
import DiaryGridView from '@/diary/DiaryList/DiaryGridView';
import { Link } from 'react-router-dom';
import * as Toast from '@radix-ui/react-toast';
import useRecentChannel from '@/logic/useRecentChannel';
import { canReadChannel, createStorageKey } from '@/logic/utils';
import DiaryListItem from './DiaryList/DiaryListItem';
import useDiaryActions from './useDiaryActions';
function DiaryChannel() {
const { chShip, chName } = useParams();
const chFlag = `${chShip}/${chName}`;
const nest = `diary/${chFlag}`;
const flag = useRouteGroup();
const vessel = useVessel(flag, window.our);
const letters = useNotesForDiary(chFlag);
const location = useLocation();
const navigate = useNavigate();
const { setRecentChannel } = useRecentChannel(flag);
const channel = useChannel(flag, nest);
useEffect(() => {
if (channel && !canReadChannel(channel, vessel)) {
navigate('../../activity');
setRecentChannel('');
}
}, [channel, vessel, navigate, setRecentChannel]);
const newNote = new URLSearchParams(location.search).get('new');
const [showToast, setShowToast] = useState(false);
const { didCopy, onCopy } = useDiaryActions({
flag: chFlag,
time: newNote || '',
});
const settings = useDiarySettings();
// for now sortMode is not actually doing anything.
// need input from design/product on what we want it to actually do, it's not spelled out in figma.
const displayMode = useDiaryDisplayMode(chFlag);
const sortMode = useDiarySortMode(chFlag);
const setDisplayMode = (view: DiaryDisplayMode) => {
useDiaryState.getState().viewDiary(chFlag, view);
};
const setSortMode = (
setting: 'time-dsc' | 'quip-dsc' | 'time-asc' | 'quip-asc'
) => {
const newSettings = setSetting<DiarySetting>(
settings,
{ sortMode: setting },
chFlag
);
useSettingsState
.getState()
.putEntry('diary', 'settings', JSON.stringify(newSettings));
};
const perms = useDiaryPerms(chFlag);
const canWrite =
perms.writers.length === 0 ||
_.intersection(perms.writers, vessel.sects).length !== 0;
useEffect(() => {
useDiaryState.getState().initialize(chFlag);
setRecentChannel(nest);
}, [chFlag, nest, setRecentChannel]);
useEffect(() => {
let timeout: any;
if (newNote) {
setShowToast(true);
timeout = setTimeout(() => {
setShowToast(false);
navigate(location.pathname, { replace: true });
}, 3000);
}
return () => {
clearTimeout(timeout);
};
}, [newNote, location, navigate]);
useDismissChannelNotifications({
nest,
markRead: useDiaryState.getState().markRead,
});
const sortedNotes = Array.from(letters).sort(([a], [b]) => {
if (sortMode === 'time-dsc') {
return b.compare(a);
}
if (sortMode === 'time-asc') {
return a.compare(b);
}
// TODO: get the time of most recent quip from each diary note, and compare that way
if (sortMode === 'quip-asc') {
return b.compare(a);
}
if (sortMode === 'quip-dsc') {
return b.compare(a);
}
return b.compare(a);
});
return (
<Layout
stickyHeader
className="flex-1 overflow-y-scroll bg-gray-50"
aside={<Outlet />}
header={
<ChannelHeader
isDiary
flag={flag}
nest={nest}
showControls
displayMode={displayMode}
setDisplayMode={setDisplayMode}
sortMode={sortMode}
setSortMode={setSortMode}
>
{canWrite ? (
<Link
to="edit"
className="button bg-blue text-white dark:text-black"
>
Add Note
</Link>
) : null}
</ChannelHeader>
}
>
<Toast.Provider>
<div className="relative flex flex-col items-center">
<Toast.Root duration={3000} defaultOpen={false} open={showToast}>
<Toast.Description asChild>
<div className="absolute z-10 flex w-[415px] -translate-x-2/4 items-center justify-between space-x-2 rounded-lg bg-white font-semibold text-black drop-shadow-lg dark:bg-gray-200">
<span className="py-2 px-4">Note successfully published</span>
<button
onClick={onCopy}
className="-mx-4 -my-2 w-[135px] rounded-r-lg bg-blue py-2 px-4 text-white dark:text-black"
>
{didCopy ? 'Copied' : 'Copy Note Link'}
</button>
</div>
</Toast.Description>
</Toast.Root>
<Toast.Viewport label="Note successfully published" />
</div>
</Toast.Provider>
<div className="p-4">
{displayMode === 'grid' ? (
<DiaryGridView notes={sortedNotes} />
) : (
<div className="h-full p-6">
<div className="mx-auto flex h-full max-w-[600px] flex-col space-y-4">
{sortedNotes.map(([time, letter]) => (
<DiaryListItem
key={time.toString()}
time={time}
letter={letter}
/>
))}
</div>
</div>
)}
</div>
</Layout>
);
}
export default DiaryChannel;