Add datetime input
This commit is contained in:
Generated
+50
-21
@@ -23,13 +23,14 @@
|
||||
"@tiptap/extension-text": "^2.6.6",
|
||||
"@tiptap/suggestion": "^2.6.4",
|
||||
"@types/throttle-debounce": "^5.0.2",
|
||||
"@welshman/app": "^0.0.4",
|
||||
"@welshman/app": "^0.0.5",
|
||||
"@welshman/lib": "^0.0.17",
|
||||
"@welshman/net": "^0.0.21",
|
||||
"@welshman/net": "^0.0.22",
|
||||
"@welshman/signer": "^0.0.5",
|
||||
"@welshman/store": "^0.0.5",
|
||||
"@welshman/util": "^0.0.30",
|
||||
"@welshman/store": "^0.0.6",
|
||||
"@welshman/util": "^0.0.31",
|
||||
"daisyui": "^4.12.10",
|
||||
"date-picker-svelte": "^2.13.0",
|
||||
"fuse.js": "^7.0.0",
|
||||
"idb": "^8.0.0",
|
||||
"nostr-editor": "^0.0.1",
|
||||
@@ -1654,15 +1655,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@welshman/app": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/app/-/app-0.0.4.tgz",
|
||||
"integrity": "sha512-Xouy66xz1tnMjlDAlxtKF+1lHVJyM2sRiC6RONDmt75HXUnuvMX19sssRy4AFwb8jychBr8EMjYanVX2EV1Sow==",
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/app/-/app-0.0.5.tgz",
|
||||
"integrity": "sha512-T7iXybwBnFN9E1GWeGQ6ZxvFrQ3EUUWHsZdG3Q+s57YxBDqDkRy+eOtxaDb2EBmgyflheERaggOlzFFTsmUjyA==",
|
||||
"dependencies": {
|
||||
"@welshman/lib": "0.0.17",
|
||||
"@welshman/net": "0.0.21",
|
||||
"@welshman/net": "0.0.22",
|
||||
"@welshman/signer": "0.0.5",
|
||||
"@welshman/store": "0.0.5",
|
||||
"@welshman/util": "0.0.30",
|
||||
"@welshman/store": "0.0.6",
|
||||
"@welshman/util": "0.0.31",
|
||||
"fuse.js": "^7.0.0",
|
||||
"idb": "^8.0.0",
|
||||
"svelte": "^4.2.18",
|
||||
@@ -1682,12 +1683,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@welshman/net": {
|
||||
"version": "0.0.21",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/net/-/net-0.0.21.tgz",
|
||||
"integrity": "sha512-BOWRevNJjyNHshxr0eFn/yBjjVIuvofyy/Q+eYuLLTRwolFkqmaiN8xuG3wFndPi5z2uuC87Ay4PmRTzp+kCSg==",
|
||||
"version": "0.0.22",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/net/-/net-0.0.22.tgz",
|
||||
"integrity": "sha512-sXdHevglDqLujQrhXFUwSPsC0Zu/SY2WWy049Citpi1nej4JnAjCbpI8XUeI1it80a84dWa+vGA5Da4OhCYkmA==",
|
||||
"dependencies": {
|
||||
"@welshman/lib": "0.0.17",
|
||||
"@welshman/util": "0.0.30",
|
||||
"@welshman/util": "0.0.31",
|
||||
"isomorphic-ws": "^5.0.0",
|
||||
"ws": "^8.16.0"
|
||||
}
|
||||
@@ -1703,20 +1704,40 @@
|
||||
"nostr-tools": "^2.7.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@welshman/store": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/store/-/store-0.0.5.tgz",
|
||||
"integrity": "sha512-AH8TsaZ63s4ln4NBO2/DjtmBFPZlxXnDiyV3wScj6Ts0vahZCinlrL8pAIfLzvZ2QvjcnFiPf081kghhr3Baaw==",
|
||||
"node_modules/@welshman/signer/node_modules/@welshman/net": {
|
||||
"version": "0.0.21",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/net/-/net-0.0.21.tgz",
|
||||
"integrity": "sha512-BOWRevNJjyNHshxr0eFn/yBjjVIuvofyy/Q+eYuLLTRwolFkqmaiN8xuG3wFndPi5z2uuC87Ay4PmRTzp+kCSg==",
|
||||
"dependencies": {
|
||||
"@welshman/lib": "0.0.17",
|
||||
"@welshman/util": "0.0.30",
|
||||
"isomorphic-ws": "^5.0.0",
|
||||
"ws": "^8.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@welshman/signer/node_modules/@welshman/util": {
|
||||
"version": "0.0.30",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/util/-/util-0.0.30.tgz",
|
||||
"integrity": "sha512-CYLtaXfCod5Xo/OCXPUGYKwT+fRwm5DU7ASqcGwPuB/vadDodT/OJPSmrMH9Pq63VY9xK4gX/I2ma/rKRokdpg==",
|
||||
"dependencies": {
|
||||
"@welshman/lib": "0.0.17",
|
||||
"nostr-tools": "^2.7.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@welshman/store": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/store/-/store-0.0.6.tgz",
|
||||
"integrity": "sha512-yZDnXcIZ2fcqvK+1W9OTRXJy3IPKE3ykFp5VnUT5bGMSRSTIyHnPO5swsgDLofe5Zswdee0lJTwE5IQBthf0pQ==",
|
||||
"dependencies": {
|
||||
"@welshman/lib": "0.0.17",
|
||||
"@welshman/util": "0.0.31",
|
||||
"svelte": "^4.2.18"
|
||||
}
|
||||
},
|
||||
"node_modules/@welshman/util": {
|
||||
"version": "0.0.30",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/util/-/util-0.0.30.tgz",
|
||||
"integrity": "sha512-CYLtaXfCod5Xo/OCXPUGYKwT+fRwm5DU7ASqcGwPuB/vadDodT/OJPSmrMH9Pq63VY9xK4gX/I2ma/rKRokdpg==",
|
||||
"version": "0.0.31",
|
||||
"resolved": "https://registry.npmjs.org/@welshman/util/-/util-0.0.31.tgz",
|
||||
"integrity": "sha512-nUv/Mto6maQx6vbCaZ0HKQRvLYRWqQzPTLsKoxSDX0HkeFP653T6raFx8TvWt+op/qBuuT8sANJactc2/qGoYg==",
|
||||
"dependencies": {
|
||||
"@welshman/lib": "0.0.17",
|
||||
"nostr-tools": "^2.7.2"
|
||||
@@ -2316,6 +2337,14 @@
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/date-picker-svelte": {
|
||||
"version": "2.13.0",
|
||||
"resolved": "https://registry.npmjs.org/date-picker-svelte/-/date-picker-svelte-2.13.0.tgz",
|
||||
"integrity": "sha512-A0MMma1uv+/sL8MwgGuEPv/UJnhR6CmWg5aR8XhYeAX/I8+RQmQh+jpwIL0Z3/g4CGo9OhNZn+VicHpvnNCCtA==",
|
||||
"peerDependencies": {
|
||||
"svelte": "^3.24.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
"@welshman/store": "^0.0.6",
|
||||
"@welshman/util": "^0.0.31",
|
||||
"daisyui": "^4.12.10",
|
||||
"date-picker-svelte": "^2.13.0",
|
||||
"fuse.js": "^7.0.0",
|
||||
"idb": "^8.0.0",
|
||||
"nostr-editor": "^0.0.1",
|
||||
|
||||
+23
-1
@@ -92,8 +92,21 @@
|
||||
|
||||
/* tiptap */
|
||||
|
||||
.input-editor, .chat-editor {
|
||||
@apply p-1 -m-1 min-h-12;
|
||||
}
|
||||
|
||||
|
||||
.tiptap[contenteditable="true"] {
|
||||
@apply max-h-[350px] overflow-y-auto rounded-box bg-base-300 p-2 px-4;
|
||||
@apply max-h-[350px] overflow-y-auto p-2 px-4;
|
||||
}
|
||||
|
||||
.chat-editor .tiptap[contenteditable="true"] {
|
||||
@apply rounded-box bg-base-300;
|
||||
}
|
||||
|
||||
.input-editor .tiptap[contenteditable="true"] {
|
||||
@apply input input-bordered p-[.65rem] h-auto;
|
||||
}
|
||||
|
||||
.tiptap pre code {
|
||||
@@ -111,3 +124,12 @@
|
||||
.link-content.link-content-selected {
|
||||
@apply bg-primary text-primary-content;
|
||||
}
|
||||
|
||||
/* date input */
|
||||
|
||||
.date-time-field {
|
||||
@apply input input-bordered px-0 rounded;
|
||||
}
|
||||
.date-time-field input {
|
||||
@apply !bg-inherit !border-none !text-inherit !w-full !h-full;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<Icon icon="gallery-send" />
|
||||
{/if}
|
||||
</Button>
|
||||
<div class="flex-grow overflow-hidden">
|
||||
<div class="flex-grow overflow-hidden chat-editor">
|
||||
<EditorContent editor={$editor} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
import Icon from "@lib/components/Icon.svelte"
|
||||
import Field from "@lib/components/Field.svelte"
|
||||
import Button from "@lib/components/Button.svelte"
|
||||
import DateTimeInput from "@lib/components/DateTimeInput.svelte"
|
||||
import {makeMention, makeIMeta} from "@app/commands"
|
||||
import {getNoteEditorOptions, addFile} from "@app/editor"
|
||||
import {pushModal} from "@app/modal"
|
||||
import {pushToast} from "@app/toast"
|
||||
|
||||
export let url
|
||||
|
||||
@@ -23,6 +25,20 @@
|
||||
const uploading = writable(false)
|
||||
|
||||
const sendMessage = () => {
|
||||
if (!title) {
|
||||
return pushToast({
|
||||
theme: "error",
|
||||
message: "Please provide a title.",
|
||||
})
|
||||
}
|
||||
|
||||
if (!start || !end) {
|
||||
return pushToast({
|
||||
theme: "error",
|
||||
message: "Please provide start and end times.",
|
||||
})
|
||||
}
|
||||
|
||||
const json = $editor.getJSON()
|
||||
const kind = isAllDay ? EVENT_DATE : EVENT_TIME
|
||||
const mentionTags = findNodes(NProfileExtension.name, json).map(m =>
|
||||
@@ -47,8 +63,8 @@
|
||||
let file: File
|
||||
let title = ""
|
||||
let location = ""
|
||||
let start = ""
|
||||
let end = ""
|
||||
let start: Date
|
||||
let end: Date
|
||||
|
||||
onMount(() => {
|
||||
editor = createEditor(getNoteEditorOptions({uploading, sendMessage}))
|
||||
@@ -71,9 +87,12 @@
|
||||
<div
|
||||
slot="input"
|
||||
class="relative z-feature flex gap-2 border-t border-solid border-base-100 bg-base-100">
|
||||
<div class="flex-grow overflow-hidden input-editor">
|
||||
<EditorContent editor={$editor} />
|
||||
</div>
|
||||
<Button
|
||||
data-tip="Add an image"
|
||||
class="center h-10 w-10 rounded-box bg-base-300 transition-colors hover:bg-base-200 tooltip"
|
||||
class="btn center tooltip"
|
||||
on:click={() => addFile($editor)}>
|
||||
{#if $uploading}
|
||||
<span class="loading loading-spinner loading-xs"></span>
|
||||
@@ -81,8 +100,17 @@
|
||||
<Icon icon="gallery-send" />
|
||||
{/if}
|
||||
</Button>
|
||||
<div class="flex-grow overflow-hidden">
|
||||
<EditorContent editor={$editor} />
|
||||
</div>
|
||||
</Field>
|
||||
<Field>
|
||||
<div slot="input" class="grid grid-cols-2 gap-2">
|
||||
<div class="flex flex-col gap-1">
|
||||
<strong>Start</strong>
|
||||
<DateTimeInput bind:value={start} />
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<strong>End</strong>
|
||||
<DateTimeInput bind:value={end} />
|
||||
</div>
|
||||
</div>
|
||||
</Field>
|
||||
|
||||
@@ -149,7 +149,6 @@ export const getChatViewOptions = (content: string) => ({
|
||||
|
||||
export const getNoteEditorOptions = ({uploading, sendMessage}: EditorOptions) => ({
|
||||
content: "",
|
||||
autofocus: true,
|
||||
extensions: [
|
||||
Document,
|
||||
Dropcursor,
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<script lang="ts">
|
||||
import cx from 'classnames'
|
||||
import {DateInput} from "date-picker-svelte"
|
||||
import {formatTimestamp} from '@welshman/app'
|
||||
import Icon from '@lib/components/Icon.svelte'
|
||||
import Button from '@lib/components/Button.svelte'
|
||||
|
||||
export let initialValue: Date | undefined = undefined
|
||||
export let value: Date | undefined = initialValue
|
||||
|
||||
const init = () => {
|
||||
if (!value) {
|
||||
value = new Date()
|
||||
value.setMinutes(0, 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
const clear = () => {
|
||||
value = undefined
|
||||
}
|
||||
</script>
|
||||
|
||||
<label class="relative">
|
||||
<DateInput format="yyyy-MM-dd HH:mm" placeholder="" bind:value />
|
||||
<div class="absolute top-0 h-12 right-2 flex gap-2 items-center cursor-pointer">
|
||||
{#if value}
|
||||
<Button on:click={clear} class="h-5">
|
||||
<Icon icon="close-circle" />
|
||||
</Button>
|
||||
{:else}
|
||||
<Button on:click={init} class="h-5">
|
||||
<Icon icon="calendar-minimalistic" />
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
</label>
|
||||
@@ -1,38 +1,10 @@
|
||||
<script context="module" lang="ts">
|
||||
import {emitter} from "@app/modal"
|
||||
|
||||
const modalHeight = tweened(0, {
|
||||
duration: 700,
|
||||
easing: quintOut,
|
||||
})
|
||||
|
||||
emitter.on("close", () => modalHeight.set(0))
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import {onMount} from "svelte"
|
||||
import {quintOut} from "svelte/easing"
|
||||
import {tweened} from "svelte/motion"
|
||||
import {fly} from "@lib/transition"
|
||||
|
||||
export let component
|
||||
export let props = {}
|
||||
|
||||
let box: HTMLElement
|
||||
let content: HTMLElement
|
||||
let naturalHeight = 0
|
||||
|
||||
onMount(() => {
|
||||
naturalHeight = content.clientHeight + 48
|
||||
modalHeight.set(naturalHeight)
|
||||
})
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="modal-box"
|
||||
bind:this={box}
|
||||
style={`height: ${$modalHeight}px`}
|
||||
class:overflow-hidden={$modalHeight !== naturalHeight}>
|
||||
<div bind:this={content}>
|
||||
<svelte:component this={component} {...props} />
|
||||
</div>
|
||||
<div class="modal-box" transition:fly={{duration: 100}}>
|
||||
<svelte:component this={component} {...props} />
|
||||
</div>
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
{#if showMenu}
|
||||
<Popover hideOnClick onClose={toggleMenu}>
|
||||
<ul
|
||||
transition:fly|local
|
||||
transition:fly
|
||||
class="menu absolute z-popover mt-2 w-full rounded-box bg-base-100 p-2 shadow-xl">
|
||||
{#if $userMembership?.topicsByUrl.has(url)}
|
||||
<li class="text-error">
|
||||
@@ -92,29 +92,29 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="my-3 h-px bg-base-200" />
|
||||
<div in:fly|local>
|
||||
<div in:fly>
|
||||
<SecondaryNavItem href={makeSpacePath(url)}>
|
||||
<Icon icon="chat-round" /> Chat
|
||||
</SecondaryNavItem>
|
||||
</div>
|
||||
<div in:fly|local={{delay: getDelay(true)}}>
|
||||
<div in:fly={{delay: getDelay(true)}}>
|
||||
<SecondaryNavItem href={makeSpacePath(url, "threads")}>
|
||||
<Icon icon="notes-minimalistic" /> Threads
|
||||
</SecondaryNavItem>
|
||||
</div>
|
||||
<div in:fly|local={{delay: getDelay()}}>
|
||||
<div in:fly={{delay: getDelay()}}>
|
||||
<SecondaryNavItem href={makeSpacePath(url, "calendar")}>
|
||||
<Icon icon="calendar-minimalistic" /> Calendar
|
||||
</SecondaryNavItem>
|
||||
</div>
|
||||
{#if rooms.length > 0}
|
||||
<div transition:slide|local={{delay: getDelay()}}>
|
||||
<div transition:slide={{delay: getDelay()}}>
|
||||
<div class="h-2" />
|
||||
<SecondaryNavHeader>Your Rooms</SecondaryNavHeader>
|
||||
</div>
|
||||
{/if}
|
||||
{#each rooms as topic, i (topic)}
|
||||
<div transition:slide|local={{delay: getDelay()}}>
|
||||
<div transition:slide={{delay: getDelay()}}>
|
||||
<SecondaryNavItem href={makeSpacePath(url, topic)}>
|
||||
<Icon icon="hashtag" />
|
||||
{topic}
|
||||
@@ -122,7 +122,7 @@
|
||||
</div>
|
||||
{/each}
|
||||
{#if otherRooms.length > 0}
|
||||
<div transition:slide|local={{delay: getDelay()}}>
|
||||
<div transition:slide={{delay: getDelay()}}>
|
||||
<div class="h-2" />
|
||||
<SecondaryNavHeader>
|
||||
{#if rooms.length > 0}
|
||||
@@ -134,14 +134,14 @@
|
||||
</div>
|
||||
{/if}
|
||||
{#each otherRooms as topic, i (topic)}
|
||||
<div transition:slide|local={{delay: getDelay()}}>
|
||||
<div transition:slide={{delay: getDelay()}}>
|
||||
<SecondaryNavItem href={makeSpacePath(url, topic)}>
|
||||
<Icon icon="hashtag" />
|
||||
{topic}
|
||||
</SecondaryNavItem>
|
||||
</div>
|
||||
{/each}
|
||||
<div in:fly|local={{delay: getDelay()}}>
|
||||
<div in:fly={{delay: getDelay()}}>
|
||||
<SecondaryNavItem on:click={addRoom}>
|
||||
<Icon icon="add-circle" />
|
||||
Create room
|
||||
|
||||
Reference in New Issue
Block a user