Browse Source

make custom events easier to edit

imwald
Silberengel 1 day ago
parent
commit
a9fbcdd8e0
  1. 4
      electron/main.cjs
  2. 8
      package.json
  3. 121
      src/components/NoteOptions/EditOrCloneEventDialog.tsx

4
electron/main.cjs

@ -5,6 +5,10 @@ const fs = require('fs')
const http = require('http') const http = require('http')
const path = require('path') const path = require('path')
// Linux WM_CLASS / Wayland app_id: must differ from the Qt Imwald desktop client (`imwald-desktop`)
// and from generic `imwald` (package.json name) or GNOME groups windows as one application.
app.setName('imwald-jumble')
/** True when running from source (`electron .`); false when packaged. */ /** True when running from source (`electron .`); false when packaged. */
const isDev = !app.isPackaged const isDev = !app.isPackaged

8
package.json

@ -1,6 +1,6 @@
{ {
"name": "imwald", "name": "imwald",
"version": "23.1.2", "version": "23.2.0",
"description": "Imwald — a user-friendly Nostr client focused on relay feed browsing, publications, and relay discovery", "description": "Imwald — a user-friendly Nostr client focused on relay feed browsing, publications, and relay discovery",
"private": true, "private": true,
"type": "module", "type": "module",
@ -181,7 +181,11 @@
], ],
"category": "Network", "category": "Network",
"maintainer": "Silberengel", "maintainer": "Silberengel",
"icon": "public/pwa-512x512.png" "icon": "public/pwa-512x512.png",
"executableName": "imwald-jumble",
"desktop": {
"StartupWMClass": "imwald-jumble"
}
} }
}, },
"overrides": { "overrides": {

121
src/components/NoteOptions/EditOrCloneEventDialog.tsx

@ -419,9 +419,9 @@ export default function EditOrCloneEventDialog(props: EditOrCloneEventDialogProp
</TabsList> </TabsList>
<TabsContent value="edit" className="flex-1 min-h-0 mt-0 data-[state=inactive]:hidden"> <TabsContent value="edit" className="flex-1 min-h-0 mt-0 data-[state=inactive]:hidden">
<ScrollArea className="h-[min(50vh,420px)] pr-3"> <ScrollArea className="h-[min(58vh,520px)] min-h-[300px] pr-3">
<div className="space-y-4 pb-2"> <div className="space-y-5 pb-4">
<div className="space-y-1"> <div className="space-y-1.5">
<label className="text-sm font-medium">{t('Event kind')}</label> <label className="text-sm font-medium">{t('Event kind')}</label>
{isCreate ? ( {isCreate ? (
<> <>
@ -475,65 +475,80 @@ export default function EditOrCloneEventDialog(props: EditOrCloneEventDialogProp
/> />
)} )}
</div> </div>
<div className="space-y-1"> <div className="space-y-1.5">
<label className="text-sm font-medium">{t('Note content')}</label> <label className="text-sm font-medium">{t('Note content')}</label>
<Textarea <Textarea
value={content} value={content}
onChange={(e) => setContent(e.target.value)} onChange={(e) => setContent(e.target.value)}
rows={10} rows={5}
className="font-mono text-sm min-h-[160px]" className="font-mono text-sm min-h-[120px] resize-y max-h-[40vh]"
/> />
</div> </div>
<div className="space-y-2"> <div className="space-y-3 rounded-lg border border-border/80 bg-muted/15 p-3 sm:p-4">
<div className="text-sm font-medium">{t('Tags')}</div> <div className="text-sm font-medium">{t('Tags')}</div>
<div className="space-y-2"> <div className="space-y-3">
{tagRows.map((row, i) => ( {tagRows.map((row, i) => (
<div <div
key={i} key={i}
className="flex flex-wrap items-start gap-1 border rounded-md p-2 bg-muted/30" className="rounded-md border border-border/60 bg-background/80 p-3 shadow-sm"
> >
{row.map((cell, j) => ( <div className="space-y-2.5">
<div key={j} className="flex items-center gap-0.5 shrink-0"> <Input
<Input value={row[0] ?? ''}
value={cell} onChange={(e) => updateRow(i, 0, e.target.value)}
onChange={(e) => updateRow(i, j, e.target.value)} placeholder={t('Tag name')}
placeholder={j === 0 ? t('Tag name') : t('Value')} className="h-9 font-mono text-sm"
className="h-8 w-[7rem] sm:w-32 font-mono text-xs" autoComplete="off"
/> />
{row.length > 1 && ( {row.length > 1 ? (
<Button <div className="space-y-2 border-l-2 border-muted pl-3">
type="button" {row.slice(1).map((cell, j) => (
variant="ghost" <div key={j + 1} className="flex gap-2 items-center min-w-0">
size="icon" <Input
className="h-8 w-8 shrink-0" value={cell}
onClick={() => removeCell(i, j)} onChange={(e) => updateRow(i, j + 1, e.target.value)}
aria-label={t('Remove value')} placeholder={t('Value')}
> className="h-9 min-w-0 flex-1 font-mono text-sm"
<Trash2 className="h-3.5 w-3.5" /> autoComplete="off"
</Button> />
)} <Button
</div> type="button"
))} variant="ghost"
<Button size="icon"
type="button" className="h-9 w-9 shrink-0"
variant="outline" onClick={() => removeCell(i, j + 1)}
size="sm" aria-label={t('Remove value')}
className="h-8" >
onClick={() => addCell(i)} <Trash2 className="h-4 w-4" />
> </Button>
<Plus className="h-3.5 w-3.5 mr-1" /> </div>
{t('Add field')} ))}
</Button> </div>
<Button ) : null}
type="button" </div>
variant="ghost" <div className="mt-3 flex flex-wrap items-center gap-2 border-t border-border/50 pt-3">
size="sm" <Button
className="h-8 ml-auto" type="button"
onClick={() => removeRow(i)} variant="outline"
aria-label={t('Remove tag')} size="sm"
> className="h-8"
<Trash2 className="h-4 w-4" /> onClick={() => addCell(i)}
</Button> >
<Plus className="h-3.5 w-3.5 mr-1.5" />
{t('Add field')}
</Button>
<Button
type="button"
variant="ghost"
size="sm"
className="h-8 text-muted-foreground hover:text-destructive"
onClick={() => removeRow(i)}
aria-label={t('Remove tag')}
>
<Trash2 className="h-4 w-4 mr-1.5" />
{t('Remove tag')}
</Button>
</div>
</div> </div>
))} ))}
</div> </div>
@ -547,7 +562,7 @@ export default function EditOrCloneEventDialog(props: EditOrCloneEventDialogProp
</TabsContent> </TabsContent>
<TabsContent value="preview" className="flex-1 min-h-0 mt-0 data-[state=inactive]:hidden"> <TabsContent value="preview" className="flex-1 min-h-0 mt-0 data-[state=inactive]:hidden">
<ScrollArea className="h-[min(50vh,420px)] pr-3"> <ScrollArea className="h-[min(58vh,520px)] min-h-[300px] pr-3">
<div className="space-y-1.5"> <div className="space-y-1.5">
{previewEvent ? ( {previewEvent ? (
<> <>
@ -575,7 +590,7 @@ export default function EditOrCloneEventDialog(props: EditOrCloneEventDialogProp
</TabsContent> </TabsContent>
<TabsContent value="json" className="flex-1 min-h-0 mt-0 data-[state=inactive]:hidden"> <TabsContent value="json" className="flex-1 min-h-0 mt-0 data-[state=inactive]:hidden">
<ScrollArea className="h-[min(50vh,420px)] pr-3"> <ScrollArea className="h-[min(58vh,520px)] min-h-[300px] pr-3">
<pre className="text-xs font-mono whitespace-pre-wrap break-words border rounded-md p-3 bg-muted/40 select-text"> <pre className="text-xs font-mono whitespace-pre-wrap break-words border rounded-md p-3 bg-muted/40 select-text">
{draftJson} {draftJson}
</pre> </pre>

Loading…
Cancel
Save