Skip to content

Commit ce062a3

Browse files
committed
lifted toast* into Container
1 parent 0a79375 commit ce062a3

27 files changed

+114
-116
lines changed

app/src/components/cardsPreview.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { For, Show, type VoidComponent } from 'solid-js'
22
import ResizingIframe from './resizingIframe'
33
import { type NoteCard } from 'shared'
4-
import { toastImpossible } from '../components/toasts'
54
import { toNoteCards, type NoteCardView } from '../uiLogic/cards'
5+
import { C } from '../topLevelAwait'
66

77
function toMainNoteCards(noteCardView: NoteCardView): NoteCard {
88
return {
@@ -12,7 +12,7 @@ function toMainNoteCards(noteCardView: NoteCardView): NoteCard {
1212
fieldValues: new Map(noteCardView.note.fieldValues),
1313
},
1414
card:
15-
noteCardView.mainCard ?? toastImpossible('No main card.', noteCardView),
15+
noteCardView.mainCard ?? C.toastImpossible('No main card.', noteCardView),
1616
}
1717
}
1818

app/src/components/cardsTable.tsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import { assertNever } from 'shared'
2424
import { agGridTheme } from '../globalState'
2525
import { Upload } from 'shared-dom'
2626
import { C } from '../topLevelAwait'
27-
import { toastError, toastImpossible, toastWarn } from './toasts'
2827
import FiltersTable from './filtersTable'
2928
import './cardsTable.css'
3029
import { type SearchParams } from '../sqlite/card'
@@ -304,12 +303,12 @@ const dataSource = {
304303
if (countishWrong && x.searchCache == null) {
305304
// asynchronously/nonblockingly build the cache
306305
db.buildCache(x.baseQuery, search).catch((e) => {
307-
toastWarn('Error building cache', e)
306+
C.toastWarn('Error building cache', e)
308307
})
309308
}
310309
})
311310
.catch((e) => {
312-
toastError('Error getting cards.', e)
311+
C.toastError('Error getting cards.', e)
313312
p.failCallback()
314313
})
315314
},
@@ -351,7 +350,7 @@ function setColumnDefs(ftsSearchActual: string, regex: RegExp) {
351350
<mark>
352351
{/* use the match's casing - not the search's (firstWord) */}
353352
{match()?.groups?.searchWord ??
354-
toastImpossible('searchWord is missing')}
353+
C.toastImpossible('searchWord is missing')}
355354
</mark>
356355
<span>{match()?.groups?.right ?? ''}</span>
357356
</Show>

app/src/components/editCardSetting.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ import {
4646
jsonCompletion,
4747
} from 'codemirror-json-schema'
4848
import Ajv from 'ajv'
49-
import { toastError } from './toasts'
5049
import { db } from '../db'
50+
import { C } from '../topLevelAwait'
5151

5252
const EditCardSetting: VoidComponent<{
5353
cardSetting: CardSetting
@@ -95,14 +95,14 @@ const EditCardSetting: VoidComponent<{
9595
try {
9696
cardSetting = JSON.parse(view.state.doc.toString()) as CardSetting
9797
} catch (error) {
98-
toastError('Invalid JSON.')
98+
C.toastError('Invalid JSON.')
9999
return
100100
}
101101
if (validate(cardSetting)) {
102102
props.setCardSetting(cardSetting)
103103
await db.bulkUploadCardSettings([cardSetting])
104104
} else {
105-
toastError(
105+
C.toastError(
106106
<>
107107
<div>Error in JSON</div>
108108
<pre>{JSON.stringify(validate.errors, null, 4)}</pre>

app/src/components/fieldHtmlEditor.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import { theme } from '../globalState'
4141
import ResizingIframe from './resizingIframe'
4242
import { format } from 'prettier'
4343
import * as prettierPluginHtml from 'prettier/plugins/html'
44-
import { toastError } from './toasts'
44+
import { C } from '../topLevelAwait'
4545

4646
let view: EditorView
4747
const FieldHtmlEditor: VoidComponent<{
@@ -147,7 +147,7 @@ function createEditorState(doc: string, theme: 'light' | 'dark') {
147147
view.setState(createEditorState(v, theme))
148148
})
149149
.catch((e) => {
150-
toastError('Error while formatting.', e)
150+
C.toastError('Error while formatting.', e)
151151
})
152152
return true
153153
},

app/src/components/fieldsEditor.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { type SetStoreFunction } from 'solid-js/store'
44
import { db } from '../db'
55
import { type MediaId } from 'shared'
66
import { ulidAsBase64Url } from '../domain/utility'
7-
import { toastFatal } from './toasts'
87
import FieldHtmlEditor from './fieldHtmlEditor'
98
import { ToggleButton } from '@kobalte/core'
109
import { ChevronDown, Code, Quote } from 'shared-dom'
@@ -34,7 +33,7 @@ export const FieldsEditor: VoidComponent<{
3433
class='text-white bg-green-600 rounded p-2 px-4 font-bold hover:bg-green-700'
3534
onClick={async () => {
3635
if (props.noteCard.cards.length === 0)
37-
toastFatal('There must be at least 1 card')
36+
C.toastFatal('There must be at least 1 card')
3837
const dp = new DOMParser()
3938
// eslint-disable-next-line solid/reactivity -- the fn isn't reactive
4039
await tx(async () => {

app/src/components/pluginsTable.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { type Plugin } from 'shared-dom'
1212
import { db } from '../db'
1313
import 'ag-grid-community/styles/ag-grid.css'
1414
import 'ag-grid-community/styles/ag-theme-alpine.css'
15-
import { toastError } from './toasts'
15+
import { C } from '../topLevelAwait'
1616

1717
LicenseManager.setLicenseKey(import.meta.env.VITE_AG_GRID_LICENSE)
1818

@@ -51,7 +51,7 @@ const columnDefs: Array<ColDef<Plugin>> = [
5151
if (props.data?.name != null) {
5252
await db.deletePlugin(props.data.name)
5353
} else {
54-
toastError(
54+
C.toastError(
5555
'props.data is null, how did this occur?',
5656
'props.data is null, how did this occur?',
5757
props,

app/src/components/resizingIframe.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
import { unwrap } from 'solid-js/store'
1212
import { db } from '../db'
1313
import { C } from '../topLevelAwait'
14-
import { toastError } from './toasts'
1514
import { debounce, leadingAndTrailing } from '@solid-primitives/scheduled'
1615

1716
const targetOrigin = '*' // highTODO make more limiting. Also implement https://stackoverflow.com/q/8169582
@@ -68,7 +67,7 @@ const ResizingIframe: VoidComponent<{
6867
targetOrigin,
6968
)
7069
} catch (error) {
71-
toastError('Error communicating with iframe.', error)
70+
C.toastError('Error communicating with iframe.', error)
7271
}
7372
},
7473
200,

app/src/globalState.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { createResource, createSignal, untrack } from 'solid-js'
22
import { cwaClient } from './trpcClient'
3-
import { toastError, toastInfo } from './components/toasts'
43
import { initThreadPool } from 'fsrs-browser'
4+
import { C } from './topLevelAwait'
55

66
// lowTODO have hub send app a message when a successful login occurs
77
export const [whoAmI] = createResource(async () => {
88
const r = await cwaClient.whoAmI.query().catch((e) => {
99
if (window.navigator.onLine) {
10-
toastError('Error occurred while verifying identity.', e)
10+
C.toastError('Error occurred while verifying identity.', e)
1111
} else {
12-
toastInfo('Cannot validate identity while offline.')
12+
C.toastInfo('Cannot validate identity while offline.')
1313
}
1414
return undefined
1515
})

app/src/hubMessenger.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import {
1515
import { ulidAsBase64Url } from './domain/utility'
1616
import { noteOrds } from 'shared-dom'
1717
import { C, tx } from './topLevelAwait'
18-
import { toastFatal } from './components/toasts'
1918

2019
export const appExpose = {
2120
addTemplate: async (rt: RemoteTemplate) => {
@@ -62,7 +61,7 @@ export const appExpose = {
6261
await tx(async () => {
6362
const template =
6463
(await db.getTemplateIdByRemoteId(rn.templateId)) ??
65-
toastFatal(`You don't have the remote template ${rn.templateId}`)
64+
C.toastFatal(`You don't have the remote template ${rn.templateId}`)
6665
const n: Note = {
6766
id: rn.id,
6867
templateId: template.id,
@@ -151,7 +150,7 @@ async function downloadImages(imgSrcs: Map<MediaId, string>) {
151150
data: await response.arrayBuffer(),
152151
})
153152
} else {
154-
return toastFatal(
153+
return C.toastFatal(
155154
`Error occured while downloading ${imgSrc}.`,
156155
`Fetching ${imgSrc} got a status code of ${response.status}`,
157156
response,

app/src/pages/home.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { db } from '../db'
1212
import { importAnki } from './importer/importer'
1313
import { augcClient } from '../trpcClient'
1414
import { C, rd } from '../topLevelAwait'
15-
import { toastImpossible } from '../components/toasts'
1615
import EditSql from '../components/editSql'
1716
import init, { Fsrs } from 'fsrs-browser'
1817
import { initFsrsTrainThreadPool } from '../globalState'
@@ -188,7 +187,7 @@ async function uploadMedia(
188187
const file =
189188
// My mental static analysis says to use `currentTarget`, but it seems to randomly be null, hence `target`. I'm confused but whatever.
190189
event.target.files?.item(0) ??
191-
toastImpossible('There should be a file selected')
190+
C.toastImpossible('There should be a file selected')
192191
const now = C.getDate()
193192
await db.bulkInsertMedia([
194193
{

app/src/pages/importer/importer.ts

+9-10
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ import {
4343
import { db } from './../../db'
4444
import _ from 'lodash'
4545
import sqliteUrl from '../../assets/sql-wasm.wasm?url'
46-
import { toastFatal, toastImpossible, toastInfo } from '../../components/toasts'
4746
import { C } from '../../topLevelAwait'
4847

4948
export async function importAnki(
@@ -55,14 +54,14 @@ export async function importAnki(
5554
const ankiExport =
5655
// My mental static analysis says to use `currentTarget`, but it seems to randomly be null, hence `target`. I'm confused but whatever.
5756
(event.target as HTMLInputElement).files?.item(0) ??
58-
toastImpossible('There should be a file selected')
57+
C.toastImpossible('There should be a file selected')
5958
const ankiEntries = await new ZipReader(
6059
new BlobReader(ankiExport),
6160
).getEntries()
6261
const sqlite =
6362
ankiEntries.find((e) => e.filename === 'collection.anki21') ??
6463
ankiEntries.find((e) => e.filename === 'collection.anki2') ??
65-
toastFatal(
64+
C.toastFatal(
6665
'`collection.anki21` or `collection.anki2` not found. When exporting from Anki, ensure that `Support older Anki versions` in the `Export` window is checked.',
6766
)
6867
await importAnkiDb(sqlite)
@@ -72,21 +71,21 @@ export async function importAnki(
7271
async function importAnkiMedia(ankiEntries: Entry[]): Promise<void> {
7372
const media =
7473
ankiEntries.find((e) => e.filename === 'media') ??
75-
toastImpossible(
74+
C.toastImpossible(
7675
`'media' not found in the provided file. Did Anki change their export format?`,
7776
)
7877
const mediaText =
7978
(await media.getData?.(new TextWriter())) ??
80-
toastImpossible(
79+
C.toastImpossible(
8180
"Impossible since we're using `getEntries` https://github.com/gildas-lormeau/zip.js/issues/371",
8281
)
8382
const parsed = checkMedia(JSON.parse(mediaText))
8483
const entryChunks = _.chunk(ankiEntries, 1000)
8584
for (let i = 0; i < entryChunks.length; i++) {
86-
toastInfo(`Media ${i}/${entryChunks.length}`)
85+
C.toastInfo(`Media ${i}/${entryChunks.length}`)
8786
await addMediaBatch(entryChunks[i]!, parsed)
8887
}
89-
toastInfo('Anki media import done!')
88+
C.toastInfo('Anki media import done!')
9089
}
9190

9291
async function addMediaBatch(
@@ -97,7 +96,7 @@ async function addMediaBatch(
9796
entries.map(async (entry) => {
9897
const array =
9998
(await entry.getData?.(new Uint8ArrayWriter())) ??
100-
toastImpossible(
99+
C.toastImpossible(
101100
"Impossible since we're using `getEntries` https://github.com/gildas-lormeau/zip.js/issues/371",
102101
)
103102
const name = nameByI[entry.filename]
@@ -164,7 +163,7 @@ async function importAnkiDb(sqlite: Entry): Promise<void> {
164163
} finally {
165164
ankiDb.close()
166165
}
167-
toastInfo('AnkiDB import done!')
166+
C.toastInfo('AnkiDB import done!')
168167
}
169168

170169
async function getAnkiDb(sqlite: Entry): Promise<Database> {
@@ -180,7 +179,7 @@ async function getAnkiDb(sqlite: Entry): Promise<Database> {
180179
async function getSqliteBuffer(sqlite: Entry): Promise<Uint8Array> {
181180
const blob =
182181
(await sqlite.getData?.(new BlobWriter())) ??
183-
toastImpossible(
182+
C.toastImpossible(
184183
"Impossible since we're using `getEntries` https://github.com/gildas-lormeau/zip.js/issues/371",
185184
)
186185
const arrayBuffer = await blob.arrayBuffer()

app/src/pages/importer/parser.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ import {
2626
dconfSingle,
2727
} from './typeChecker'
2828
import _ from 'lodash'
29-
import { toastFatal, toastImpossible } from '../../components/toasts'
3029
import { z } from 'zod'
30+
import { C } from '../../topLevelAwait'
3131

3232
function parseField(fld: Fld): Field {
3333
return {
@@ -57,7 +57,7 @@ function parseTemplateType(model: Model): TemplateType {
5757
}
5858
case 1: {
5959
if (model.tmpls.length !== 1)
60-
toastImpossible(
60+
C.toastImpossible(
6161
`Cloze template have only 1 template, but got ${model.tmpls.length}`,
6262
)
6363
const tmpl = model.tmpls[0]!
@@ -67,7 +67,7 @@ function parseTemplateType(model: Model): TemplateType {
6767
}
6868
}
6969
default:
70-
toastImpossible(
70+
return C.toastImpossible(
7171
`Only 0 or 1 are possible model types, but got ${model.type}`,
7272
)
7373
}
@@ -98,11 +98,11 @@ export function parseNote(
9898
): PNote {
9999
const templateId = note.mid.toString() as TemplateId // medTODO
100100
const template = templates.get(templateId)
101-
if (template == null) toastFatal(`Template ${templateId} not found`)
101+
if (template == null) return C.toastFatal(`Template ${templateId} not found`)
102102
const fields = template.fields.map((f) => f.name)
103103
const values = note.flds.split('\x1f')
104104
if (fields.length !== values.length)
105-
toastFatal(
105+
C.toastFatal(
106106
`The length of fields (${fields.length}) and values (${values.length}) for noteId=${note.id} don't match.`,
107107
)
108108
return {
@@ -129,10 +129,11 @@ export function parseCard(
129129
decks: Decks,
130130
): PCard {
131131
const note = notes.get(card.nid)
132-
if (note == null) toastFatal(`Note ${card.nid} not found`)
132+
if (note == null) return C.toastFatal(`Note ${card.nid} not found`)
133133
const template = templates.get(note.templateId)
134-
if (template == null) toastFatal(`Template ${note.templateId} not found`)
135-
const deck = decks[card.did] ?? toastFatal(`Deck ${card.did} not found`)
134+
if (template == null)
135+
return C.toastFatal(`Template ${note.templateId} not found`)
136+
const deck = decks[card.did] ?? C.toastFatal(`Deck ${card.did} not found`)
136137
return {
137138
id: card.id.toString() as CardId, // medTODO
138139
noteId: card.nid.toString() as NoteId, // medTODO

app/src/pages/importer/typeChecker.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { type Ord } from 'shared'
22
import { z, type SafeParseReturnType } from 'zod'
3-
import { toastFatal } from '../../components/toasts'
3+
import { C } from '../../topLevelAwait'
44

55
const tmpl = z.object({
66
name: z.string(),
@@ -157,7 +157,7 @@ function parse<Input, Output>(
157157
if (result.success) {
158158
return result.data
159159
} else {
160-
return toastFatal({
160+
return C.toastFatal({
161161
jsx: (
162162
<>
163163
<div>Error parsing the following:</div>

app/src/pages/plugins.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { type JSX } from 'solid-js'
22
import PluginsTable from '../components/pluginsTable'
33
import { db } from '../db'
44
import { parsePluginNpmPackage } from 'shared-dom'
5-
import { toastImpossible, toastInfo } from '../components/toasts'
65
import { C } from '../topLevelAwait'
76

87
export default function Plugins(): JSX.Element {
@@ -29,13 +28,13 @@ async function importPlugin(
2928
const pluginTgz =
3029
// My mental static analysis says to use `currentTarget`, but it seems to randomly be null, hence `target`. I'm confused but whatever.
3130
event.target.files?.item(0) ??
32-
toastImpossible('There should be a file selected')
31+
C.toastImpossible('There should be a file selected')
3332
const plugin = await parsePluginNpmPackage(pluginTgz)
3433
const now = C.getDate()
3534
await db.upsertPlugin({
3635
...plugin,
3736
created: now,
3837
updated: now,
3938
})
40-
toastInfo('Plugin upserted!')
39+
C.toastInfo('Plugin upserted!')
4140
}

0 commit comments

Comments
 (0)