forked from coracle/flotilla
Add sticky submit buttons to settings pages
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {onMount, mount, unmount, createRawSnippet} from "svelte"
|
import {onMount, mount, unmount} from "svelte"
|
||||||
import Drawer from "@lib/components/Drawer.svelte"
|
import Drawer from "@lib/components/Drawer.svelte"
|
||||||
import Dialog from "@lib/components/Dialog.svelte"
|
import Dialog from "@lib/components/Dialog.svelte"
|
||||||
import {modal, clearModals} from "@app/util/modal"
|
import {modal, clearModals} from "@app/util/modal"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import cx from "classnames"
|
|
||||||
import {goto} from "$app/navigation"
|
import {goto} from "$app/navigation"
|
||||||
import type {RoomMeta} from "@welshman/util"
|
import type {RoomMeta} from "@welshman/util"
|
||||||
import {displayRelayUrl, makeRoomMeta} from "@welshman/util"
|
import {displayRelayUrl, makeRoomMeta} from "@welshman/util"
|
||||||
@@ -16,7 +15,6 @@
|
|||||||
import Microphone from "@assets/icons/microphone.svg?dataurl"
|
import Microphone from "@assets/icons/microphone.svg?dataurl"
|
||||||
import Bookmark from "@assets/icons/bookmark.svg?dataurl"
|
import Bookmark from "@assets/icons/bookmark.svg?dataurl"
|
||||||
import VolumeLoud from "@assets/icons/volume-loud.svg?dataurl"
|
import VolumeLoud from "@assets/icons/volume-loud.svg?dataurl"
|
||||||
import VolumeCross from "@assets/icons/volume-cross.svg?dataurl"
|
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
import Icon from "@lib/components/Icon.svelte"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import Confirm from "@lib/components/Confirm.svelte"
|
import Confirm from "@lib/components/Confirm.svelte"
|
||||||
@@ -34,7 +32,6 @@
|
|||||||
deriveUserIsRoomAdmin,
|
deriveUserIsRoomAdmin,
|
||||||
deriveUserRoomMembershipStatus,
|
deriveUserRoomMembershipStatus,
|
||||||
deriveUserRooms,
|
deriveUserRooms,
|
||||||
userSettingsValues,
|
|
||||||
deriveIsMuted,
|
deriveIsMuted,
|
||||||
MembershipStatus,
|
MembershipStatus,
|
||||||
} from "@app/core/state"
|
} from "@app/core/state"
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {displayUrl} from "@welshman/lib"
|
import {displayUrl} from "@welshman/lib"
|
||||||
import {AuthStatus} from "@welshman/net"
|
|
||||||
import {preventDefault} from "@lib/html"
|
import {preventDefault} from "@lib/html"
|
||||||
import Spinner from "@lib/components/Spinner.svelte"
|
import Spinner from "@lib/components/Spinner.svelte"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
@@ -14,9 +13,8 @@
|
|||||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||||
import {pushToast} from "@app/util/toast"
|
import {pushToast} from "@app/util/toast"
|
||||||
import {pushModal} from "@app/util/modal"
|
|
||||||
import {attemptRelayAccess} from "@app/core/commands"
|
import {attemptRelayAccess} from "@app/core/commands"
|
||||||
import {deriveSocket, parseInviteLink} from "@app/core/state"
|
import {parseInviteLink} from "@app/core/state"
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
url: string
|
url: string
|
||||||
@@ -27,8 +25,6 @@
|
|||||||
|
|
||||||
const back = () => history.back()
|
const back = () => history.back()
|
||||||
|
|
||||||
const socket = deriveSocket(url)
|
|
||||||
|
|
||||||
const join = async () => {
|
const join = async () => {
|
||||||
loading = true
|
loading = true
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type {Snippet} from "svelte"
|
|
||||||
import {dissoc} from "@welshman/lib"
|
import {dissoc} from "@welshman/lib"
|
||||||
import {Pool, AuthStatus} from "@welshman/net"
|
|
||||||
import {goto} from "$app/navigation"
|
import {goto} from "$app/navigation"
|
||||||
import {preventDefault} from "@lib/html"
|
import {preventDefault} from "@lib/html"
|
||||||
import {slideAndFade} from "@lib/transition"
|
import {slideAndFade} from "@lib/transition"
|
||||||
@@ -17,9 +15,7 @@
|
|||||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||||
import RelaySummary from "@app/components/RelaySummary.svelte"
|
import RelaySummary from "@app/components/RelaySummary.svelte"
|
||||||
import SpaceJoin from "@app/components/SpaceJoin.svelte"
|
|
||||||
import {pushToast} from "@app/util/toast"
|
import {pushToast} from "@app/util/toast"
|
||||||
import {pushModal} from "@app/util/modal"
|
|
||||||
import {makeSpacePath} from "@app/util/routes"
|
import {makeSpacePath} from "@app/util/routes"
|
||||||
import {relaysMostlyRestricted, parseInviteLink} from "@app/core/state"
|
import {relaysMostlyRestricted, parseInviteLink} from "@app/core/state"
|
||||||
import {attemptRelayAccess, addSpaceMembership, broadcastUserData} from "@app/core/commands"
|
import {attemptRelayAccess, addSpaceMembership, broadcastUserData} from "@app/core/commands"
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {onMount} from "svelte"
|
import {onMount} from "svelte"
|
||||||
import {goto} from "$app/navigation"
|
import {goto} from "$app/navigation"
|
||||||
import {sleep, dissoc} from "@welshman/lib"
|
import {dissoc} from "@welshman/lib"
|
||||||
import {Pool, AuthStatus, SocketStatus} from "@welshman/net"
|
|
||||||
import {deriveRelay} from "@welshman/app"
|
|
||||||
import {displayRelayUrl} from "@welshman/util"
|
|
||||||
import {preventDefault} from "@lib/html"
|
import {preventDefault} from "@lib/html"
|
||||||
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
|
import AltArrowLeft from "@assets/icons/alt-arrow-left.svg?dataurl"
|
||||||
import AltArrowRight from "@assets/icons/alt-arrow-right.svg?dataurl"
|
import AltArrowRight from "@assets/icons/alt-arrow-right.svg?dataurl"
|
||||||
@@ -15,7 +12,6 @@
|
|||||||
import Modal from "@lib/components/Modal.svelte"
|
import Modal from "@lib/components/Modal.svelte"
|
||||||
import ModalBody from "@lib/components/ModalBody.svelte"
|
import ModalBody from "@lib/components/ModalBody.svelte"
|
||||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||||
import FieldInline from "@lib/components/FieldInline.svelte"
|
|
||||||
import StatusIndicator from "@lib/components/StatusIndicator.svelte"
|
import StatusIndicator from "@lib/components/StatusIndicator.svelte"
|
||||||
import RelaySummary from "@app/components/RelaySummary.svelte"
|
import RelaySummary from "@app/components/RelaySummary.svelte"
|
||||||
import SocketStatusIndicator from "@app/components/SocketStatusIndicator.svelte"
|
import SocketStatusIndicator from "@app/components/SocketStatusIndicator.svelte"
|
||||||
@@ -26,7 +22,7 @@
|
|||||||
broadcastUserData,
|
broadcastUserData,
|
||||||
setSpaceNotifications,
|
setSpaceNotifications,
|
||||||
} from "@app/core/commands"
|
} from "@app/core/commands"
|
||||||
import {relaysMostlyRestricted, deriveSpaceMembers, notificationSettings} from "@app/core/state"
|
import {relaysMostlyRestricted, notificationSettings} from "@app/core/state"
|
||||||
import {pushModal} from "@app/util/modal"
|
import {pushModal} from "@app/util/modal"
|
||||||
import {pushToast} from "@app/util/toast"
|
import {pushToast} from "@app/util/toast"
|
||||||
import {makeSpacePath} from "@app/util/routes"
|
import {makeSpacePath} from "@app/util/routes"
|
||||||
@@ -38,9 +34,6 @@
|
|||||||
|
|
||||||
const {url}: Props = $props()
|
const {url}: Props = $props()
|
||||||
|
|
||||||
const relay = deriveRelay(url)
|
|
||||||
const members = deriveSpaceMembers(url)
|
|
||||||
|
|
||||||
const back = () => history.back()
|
const back = () => history.back()
|
||||||
|
|
||||||
const join = async () => {
|
const join = async () => {
|
||||||
|
|||||||
@@ -48,7 +48,6 @@
|
|||||||
deriveUserCanCreateRoom,
|
deriveUserCanCreateRoom,
|
||||||
deriveUserIsSpaceAdmin,
|
deriveUserIsSpaceAdmin,
|
||||||
deriveEventsForUrl,
|
deriveEventsForUrl,
|
||||||
userSettingsValues,
|
|
||||||
notificationSettings,
|
notificationSettings,
|
||||||
deriveIsMuted,
|
deriveIsMuted,
|
||||||
} from "@app/core/state"
|
} from "@app/core/state"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import RoomNameWithImage from "@app/components/RoomNameWithImage.svelte"
|
import RoomNameWithImage from "@app/components/RoomNameWithImage.svelte"
|
||||||
import {makeRoomPath} from "@app/util/routes"
|
import {makeRoomPath} from "@app/util/routes"
|
||||||
import {notifications} from "@app/util/notifications"
|
import {notifications} from "@app/util/notifications"
|
||||||
import {userSettingsValues, deriveIsMuted} from "@app/core/state"
|
import {deriveIsMuted} from "@app/core/state"
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
url: any
|
url: any
|
||||||
|
|||||||
@@ -31,8 +31,6 @@ import {
|
|||||||
identity,
|
identity,
|
||||||
now,
|
now,
|
||||||
groupBy,
|
groupBy,
|
||||||
nth,
|
|
||||||
nthEq,
|
|
||||||
maybe,
|
maybe,
|
||||||
throttle,
|
throttle,
|
||||||
} from "@welshman/lib"
|
} from "@welshman/lib"
|
||||||
@@ -64,7 +62,6 @@ import {
|
|||||||
getEventPath,
|
getEventPath,
|
||||||
goToEvent,
|
goToEvent,
|
||||||
} from "@app/util/routes"
|
} from "@app/util/routes"
|
||||||
import type {SpaceNotificationSettings} from "@app/core/state"
|
|
||||||
import {
|
import {
|
||||||
DM_KINDS,
|
DM_KINDS,
|
||||||
CONTENT_KINDS,
|
CONTENT_KINDS,
|
||||||
@@ -75,15 +72,12 @@ import {
|
|||||||
notificationState,
|
notificationState,
|
||||||
chatsById,
|
chatsById,
|
||||||
hasNip29,
|
hasNip29,
|
||||||
getSettings,
|
|
||||||
userSettingsValues,
|
userSettingsValues,
|
||||||
userGroupList,
|
userGroupList,
|
||||||
getSpaceUrlsFromGroupList,
|
getSpaceUrlsFromGroupList,
|
||||||
getSpaceRoomsFromGroupList,
|
getSpaceRoomsFromGroupList,
|
||||||
makeCommentFilter,
|
makeCommentFilter,
|
||||||
userSpaceUrls,
|
userSpaceUrls,
|
||||||
splitRoomId,
|
|
||||||
makeRoomId,
|
|
||||||
isMuted,
|
isMuted,
|
||||||
device,
|
device,
|
||||||
} from "@app/core/state"
|
} from "@app/core/state"
|
||||||
@@ -284,7 +278,6 @@ export const onNotification = call(() => {
|
|||||||
if (!unsubscribe) {
|
if (!unsubscribe) {
|
||||||
unsubscribe = on(repository, "update", ({added}) => {
|
unsubscribe = on(repository, "update", ({added}) => {
|
||||||
const $pubkey = pubkey.get()
|
const $pubkey = pubkey.get()
|
||||||
const {alerts} = getSettings()
|
|
||||||
|
|
||||||
for (const event of added) {
|
for (const event of added) {
|
||||||
if (event.pubkey == $pubkey) {
|
if (event.pubkey == $pubkey) {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type {Component} from "svelte"
|
import type {Component} from "svelte"
|
||||||
import cx from "classnames"
|
import cx from "classnames"
|
||||||
import {onMount} from "svelte"
|
|
||||||
import {noop} from "@welshman/lib"
|
import {noop} from "@welshman/lib"
|
||||||
import {fade, fly} from "@lib/transition"
|
import {fade, fly} from "@lib/transition"
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,19 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import cx from "classnames"
|
import cx from "classnames"
|
||||||
import {sleep, equals, remove} from "@welshman/lib"
|
import {sleep} from "@welshman/lib"
|
||||||
import {displayRelayUrl} from "@welshman/util"
|
|
||||||
import {Capacitor} from "@capacitor/core"
|
import {Capacitor} from "@capacitor/core"
|
||||||
import {Badge} from "@capawesome/capacitor-badge"
|
import {Badge} from "@capawesome/capacitor-badge"
|
||||||
import CloseCircle from "@assets/icons/close-circle.svg?dataurl"
|
|
||||||
import {preventDefault} from "@lib/html"
|
import {preventDefault} from "@lib/html"
|
||||||
import Icon from "@lib/components/Icon.svelte"
|
|
||||||
import Spinner from "@lib/components/Spinner.svelte"
|
import Spinner from "@lib/components/Spinner.svelte"
|
||||||
import Button from "@lib/components/Button.svelte"
|
import Button from "@lib/components/Button.svelte"
|
||||||
import RoomName from "@app/components/RoomName.svelte"
|
|
||||||
import {pushToast} from "@app/util/toast"
|
import {pushToast} from "@app/util/toast"
|
||||||
import {Push, clearBadges} from "@app/util/notifications"
|
import {Push, clearBadges} from "@app/util/notifications"
|
||||||
import {notificationSettings, userSettingsValues, splitRoomId} from "@app/core/state"
|
import {notificationSettings} from "@app/core/state"
|
||||||
import {publishSettings} from "@app/core/commands"
|
|
||||||
|
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
settings = {...notificationSettings.get()}
|
settings = {...notificationSettings.get()}
|
||||||
}
|
}
|
||||||
|
|
||||||
const removeMutedRoom = (id: string) => {
|
|
||||||
muted_rooms = remove(id, muted_rooms)
|
|
||||||
}
|
|
||||||
|
|
||||||
const onsubmit = preventDefault(async () => {
|
const onsubmit = preventDefault(async () => {
|
||||||
loading = true
|
loading = true
|
||||||
|
|
||||||
@@ -46,10 +37,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!equals(muted_rooms, $userSettingsValues.muted_rooms)) {
|
|
||||||
publishSettings($state.snapshot({...$userSettingsValues, muted_rooms}))
|
|
||||||
}
|
|
||||||
|
|
||||||
notificationSettings.set(settings)
|
notificationSettings.set(settings)
|
||||||
|
|
||||||
pushToast({message: "Your settings have been saved!"})
|
pushToast({message: "Your settings have been saved!"})
|
||||||
@@ -60,7 +47,6 @@
|
|||||||
|
|
||||||
let loading = $state(false)
|
let loading = $state(false)
|
||||||
let settings = $state({...notificationSettings.get()})
|
let settings = $state({...notificationSettings.get()})
|
||||||
let muted_rooms = $state($userSettingsValues.muted_rooms)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form class="content column gap-4" {onsubmit}>
|
<form class="content column gap-4" {onsubmit}>
|
||||||
@@ -105,7 +91,8 @@
|
|||||||
<input type="checkbox" class="toggle toggle-primary" bind:checked={settings.messages} />
|
<input type="checkbox" class="toggle toggle-primary" bind:checked={settings.messages} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4 flex flex-row items-center justify-between gap-4">
|
<div
|
||||||
|
class="card2 bg-alt sticky -bottom-3 shadow-md flex flex-row items-center justify-between gap-4">
|
||||||
<Button class="btn btn-neutral" onclick={reset} disabled={loading}>Discard Changes</Button>
|
<Button class="btn btn-neutral" onclick={reset} disabled={loading}>Discard Changes</Button>
|
||||||
<Button type="submit" class="btn btn-primary" disabled={loading}>
|
<Button type="submit" class="btn btn-primary" disabled={loading}>
|
||||||
<Spinner {loading}>Save Changes</Spinner>
|
<Spinner {loading}>Save Changes</Spinner>
|
||||||
|
|||||||
@@ -87,6 +87,28 @@
|
|||||||
</div>
|
</div>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</Field>
|
</Field>
|
||||||
|
</div>
|
||||||
|
<div class="card2 bg-alt col-4 shadow-md">
|
||||||
|
<strong class="text-lg">Accessibility</strong>
|
||||||
|
<Field>
|
||||||
|
{#snippet label()}
|
||||||
|
<p>Font size</p>
|
||||||
|
{/snippet}
|
||||||
|
{#snippet secondary()}
|
||||||
|
<p>{Math.round(settings.font_size * 100)}%</p>
|
||||||
|
{/snippet}
|
||||||
|
{#snippet input()}
|
||||||
|
<input
|
||||||
|
class="range range-primary"
|
||||||
|
type="range"
|
||||||
|
min="0.8"
|
||||||
|
max="1.3"
|
||||||
|
step="0.05"
|
||||||
|
bind:value={settings.font_size} />
|
||||||
|
{/snippet}
|
||||||
|
</Field>
|
||||||
|
</div>
|
||||||
|
<div class="card2 bg-alt col-4 shadow-md">
|
||||||
<strong class="text-lg">Editor Settings</strong>
|
<strong class="text-lg">Editor Settings</strong>
|
||||||
<FieldInline>
|
<FieldInline>
|
||||||
{#snippet label()}
|
{#snippet label()}
|
||||||
@@ -123,27 +145,10 @@
|
|||||||
<p>Choose a media server type and url for files you upload to {PLATFORM_NAME}.</p>
|
<p>Choose a media server type and url for files you upload to {PLATFORM_NAME}.</p>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</Field>
|
</Field>
|
||||||
<strong class="text-lg">Accessibility</strong>
|
</div>
|
||||||
<Field>
|
<div
|
||||||
{#snippet label()}
|
class="card2 bg-alt sticky -bottom-3 shadow-md flex flex-row items-center justify-between gap-4">
|
||||||
<p>Font size</p>
|
<Button class="btn btn-neutral" onclick={reset}>Discard Changes</Button>
|
||||||
{/snippet}
|
<Button type="submit" class="btn btn-primary">Save Changes</Button>
|
||||||
{#snippet secondary()}
|
|
||||||
<p>{Math.round(settings.font_size * 100)}%</p>
|
|
||||||
{/snippet}
|
|
||||||
{#snippet input()}
|
|
||||||
<input
|
|
||||||
class="range range-primary"
|
|
||||||
type="range"
|
|
||||||
min="0.8"
|
|
||||||
max="1.3"
|
|
||||||
step="0.05"
|
|
||||||
bind:value={settings.font_size} />
|
|
||||||
{/snippet}
|
|
||||||
</Field>
|
|
||||||
<div class="mt-4 flex flex-row items-center justify-between gap-4">
|
|
||||||
<Button class="btn btn-neutral" onclick={reset}>Discard Changes</Button>
|
|
||||||
<Button type="submit" class="btn btn-primary">Save Changes</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -50,9 +50,10 @@
|
|||||||
Allow {PLATFORM_NAME} to collect anonymous usage data.
|
Allow {PLATFORM_NAME} to collect anonymous usage data.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4 flex flex-row items-center justify-between gap-4">
|
</div>
|
||||||
<Button class="btn btn-neutral" onclick={reset}>Discard Changes</Button>
|
<div
|
||||||
<Button type="submit" class="btn btn-primary">Save Changes</Button>
|
class="card2 bg-alt sticky -bottom-3 shadow-md flex flex-row items-center justify-between gap-4">
|
||||||
</div>
|
<Button class="btn btn-neutral" onclick={reset}>Discard Changes</Button>
|
||||||
|
<Button type="submit" class="btn btn-primary">Save Changes</Button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {readable, derived as _derived} from "svelte/store"
|
import {readable} from "svelte/store"
|
||||||
import {onMount, onDestroy} from "svelte"
|
import {onMount, onDestroy} from "svelte"
|
||||||
import {page} from "$app/stores"
|
import {page} from "$app/stores"
|
||||||
import type {Readable} from "svelte/store"
|
import type {Readable} from "svelte/store"
|
||||||
import type {MakeNonOptional} from "@welshman/lib"
|
import type {MakeNonOptional} from "@welshman/lib"
|
||||||
import {now, int, append, remove, formatTimestampAsDate, ago, MINUTE} from "@welshman/lib"
|
import {now, int, formatTimestampAsDate, ago, MINUTE} from "@welshman/lib"
|
||||||
import type {TrustedEvent, EventContent} from "@welshman/util"
|
import type {TrustedEvent, EventContent} from "@welshman/util"
|
||||||
import {throttled} from "@welshman/store"
|
|
||||||
import {
|
import {
|
||||||
makeEvent,
|
makeEvent,
|
||||||
makeRoomMeta,
|
makeRoomMeta,
|
||||||
|
|||||||
Reference in New Issue
Block a user