mirror of
https://github.com/coracle-social/flotilla.git
synced 2025-12-10 10:57:04 +00:00
Rework css on room view to avoid losing input visibility
This commit is contained in:
24
src/app.css
24
src/app.css
@@ -329,3 +329,27 @@ emoji-picker {
|
|||||||
progress[value]::-webkit-progress-value {
|
progress[value]::-webkit-progress-value {
|
||||||
transition: width 0.5s;
|
transition: width 0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* content width for fixed elements */
|
||||||
|
|
||||||
|
.cw {
|
||||||
|
@apply w-full md:w-[calc(100%-18.5rem)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* chat view */
|
||||||
|
|
||||||
|
.chat__page-bar {
|
||||||
|
@apply cw !fixed top-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat__messages {
|
||||||
|
@apply cw fixed top-12 flex h-[calc(100%-10rem)] flex-col-reverse overflow-y-auto overflow-x-hidden md:h-[calc(100%-6rem)];
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat__compose {
|
||||||
|
@apply cw fixed bottom-14 md:bottom-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat__scroll-down {
|
||||||
|
@apply fixed bottom-28 right-4 md:bottom-16;
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
const {...props}: Props = $props()
|
const {...props}: Props = $props()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="relative z-feature mx-2 rounded-xl pt-2 {props.class}">
|
<div class="relative z-feature rounded-xl px-2 pt-2 {props.class}">
|
||||||
<div
|
<div
|
||||||
class="flex min-h-12 items-center justify-between gap-4 rounded-xl bg-base-100 px-4 shadow-xl">
|
class="flex min-h-12 items-center justify-between gap-4 rounded-xl bg-base-100 px-4 shadow-xl">
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
|
|||||||
@@ -125,6 +125,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
<Divider>Your Rooms</Divider>
|
||||||
<div class="grid grid-cols-3 gap-2">
|
<div class="grid grid-cols-3 gap-2">
|
||||||
<Link href={threadsPath} class="btn btn-primary">
|
<Link href={threadsPath} class="btn btn-primary">
|
||||||
<div class="relative flex items-center gap-2">
|
<div class="relative flex items-center gap-2">
|
||||||
@@ -167,6 +168,9 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</Link>
|
</Link>
|
||||||
{/each}
|
{/each}
|
||||||
|
</div>
|
||||||
|
<Divider>Other Rooms</Divider>
|
||||||
|
<div class="grid grid-cols-3 gap-2">
|
||||||
{#each $otherRooms as room (room)}
|
{#each $otherRooms as room (room)}
|
||||||
<Link href={makeRoomPath(url, room)} class="btn btn-neutral">
|
<Link href={makeRoomPath(url, room)} class="btn btn-neutral">
|
||||||
<div class="relative flex min-w-0 items-center gap-2 overflow-hidden text-nowrap">
|
<div class="relative flex min-w-0 items-center gap-2 overflow-hidden text-nowrap">
|
||||||
|
|||||||
@@ -134,6 +134,8 @@
|
|||||||
let parent: TrustedEvent | undefined = $state()
|
let parent: TrustedEvent | undefined = $state()
|
||||||
let element: HTMLElement | undefined = $state()
|
let element: HTMLElement | undefined = $state()
|
||||||
let newMessages: HTMLElement | undefined = $state()
|
let newMessages: HTMLElement | undefined = $state()
|
||||||
|
let parentPreview: HTMLElement | undefined = $state()
|
||||||
|
let dynamicPadding: HTMLElement | undefined = $state()
|
||||||
let newMessagesSeen = false
|
let newMessagesSeen = false
|
||||||
let showFixedNewMessages = $state(false)
|
let showFixedNewMessages = $state(false)
|
||||||
let showScrollButton = $state(false)
|
let showScrollButton = $state(false)
|
||||||
@@ -208,6 +210,16 @@
|
|||||||
loadingEvents = false
|
loadingEvents = false
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
const observer = new ResizeObserver(() => {
|
||||||
|
dynamicPadding!.style.minHeight = `${parentPreview!.offsetHeight}px`
|
||||||
|
})
|
||||||
|
|
||||||
|
observer.observe(parentPreview!)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
observer.unobserve(parentPreview!)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
@@ -220,100 +232,101 @@
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="relative flex h-full flex-col">
|
<PageBar class="chat__page-bar">
|
||||||
<PageBar>
|
{#snippet icon()}
|
||||||
{#snippet icon()}
|
<div class="center">
|
||||||
<div class="center">
|
<Icon icon="hashtag" />
|
||||||
<Icon icon="hashtag" />
|
|
||||||
</div>
|
|
||||||
{/snippet}
|
|
||||||
{#snippet title()}
|
|
||||||
<strong>
|
|
||||||
<ChannelName {url} {room} />
|
|
||||||
</strong>
|
|
||||||
{/snippet}
|
|
||||||
{#snippet action()}
|
|
||||||
<div class="row-2">
|
|
||||||
{#if room !== GENERAL}
|
|
||||||
{#if $userRoomsByUrl.get(url)?.has(room)}
|
|
||||||
<Button class="btn btn-neutral btn-sm" onclick={leaveRoom}>
|
|
||||||
<Icon icon="arrows-a-logout-2" />
|
|
||||||
Leave Room
|
|
||||||
</Button>
|
|
||||||
{:else}
|
|
||||||
<Button class="btn btn-neutral btn-sm" disabled={joiningRoom} onclick={joinRoom}>
|
|
||||||
{#if joiningRoom}
|
|
||||||
<span class="loading loading-spinner loading-sm"></span>
|
|
||||||
{:else}
|
|
||||||
<Icon icon="login-2" />
|
|
||||||
{/if}
|
|
||||||
Join Room
|
|
||||||
</Button>
|
|
||||||
{/if}
|
|
||||||
{/if}
|
|
||||||
<MenuSpaceButton {url} />
|
|
||||||
</div>
|
|
||||||
{/snippet}
|
|
||||||
</PageBar>
|
|
||||||
<div
|
|
||||||
class="scroll-container -mt-2 flex flex-grow flex-col-reverse overflow-y-auto overflow-x-hidden py-2"
|
|
||||||
onscroll={onScroll}
|
|
||||||
bind:this={element}>
|
|
||||||
{#each elements as { type, id, value, showPubkey } (id)}
|
|
||||||
{#if type === "new-messages"}
|
|
||||||
<div
|
|
||||||
bind:this={newMessages}
|
|
||||||
class="flex items-center py-2 text-xs transition-colors"
|
|
||||||
class:opacity-0={showFixedNewMessages}>
|
|
||||||
<div class="h-px flex-grow bg-primary"></div>
|
|
||||||
<p class="rounded-full bg-primary px-2 py-1 text-primary-content">New Messages</p>
|
|
||||||
<div class="h-px flex-grow bg-primary"></div>
|
|
||||||
</div>
|
|
||||||
{:else if type === "date"}
|
|
||||||
<Divider>{value}</Divider>
|
|
||||||
{:else}
|
|
||||||
<div in:slide class:-mt-1={!showPubkey}>
|
|
||||||
<ChannelMessage
|
|
||||||
{url}
|
|
||||||
{room}
|
|
||||||
{replyTo}
|
|
||||||
event={$state.snapshot(value as TrustedEvent)}
|
|
||||||
{showPubkey} />
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
<p class="flex h-10 items-center justify-center py-20">
|
|
||||||
{#if loadingEvents}
|
|
||||||
<Spinner loading={loadingEvents}>Looking for messages...</Spinner>
|
|
||||||
{:else}
|
|
||||||
<Spinner>End of message history</Spinner>
|
|
||||||
{/if}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{#if showFixedNewMessages}
|
|
||||||
<div class="relative z-feature flex justify-center">
|
|
||||||
<div transition:fly={{duration: 200}} class="fixed top-12">
|
|
||||||
<Button class="btn btn-primary btn-xs rounded-full" onclick={scrollToNewMessages}>
|
|
||||||
New Messages
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/snippet}
|
||||||
<div>
|
{#snippet title()}
|
||||||
|
<strong>
|
||||||
|
<ChannelName {url} {room} />
|
||||||
|
</strong>
|
||||||
|
{/snippet}
|
||||||
|
{#snippet action()}
|
||||||
|
<div class="row-2">
|
||||||
|
{#if room !== GENERAL}
|
||||||
|
{#if $userRoomsByUrl.get(url)?.has(room)}
|
||||||
|
<Button class="btn btn-neutral btn-sm" onclick={leaveRoom}>
|
||||||
|
<Icon icon="arrows-a-logout-2" />
|
||||||
|
Leave Room
|
||||||
|
</Button>
|
||||||
|
{:else}
|
||||||
|
<Button class="btn btn-neutral btn-sm" disabled={joiningRoom} onclick={joinRoom}>
|
||||||
|
{#if joiningRoom}
|
||||||
|
<span class="loading loading-spinner loading-sm"></span>
|
||||||
|
{:else}
|
||||||
|
<Icon icon="login-2" />
|
||||||
|
{/if}
|
||||||
|
Join Room
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
|
{/if}
|
||||||
|
<MenuSpaceButton {url} />
|
||||||
|
</div>
|
||||||
|
{/snippet}
|
||||||
|
</PageBar>
|
||||||
|
|
||||||
|
<div class="chat__messages scroll-container" onscroll={onScroll} bind:this={element}>
|
||||||
|
<div bind:this={dynamicPadding}></div>
|
||||||
|
{#each elements as { type, id, value, showPubkey } (id)}
|
||||||
|
{#if type === "new-messages"}
|
||||||
|
<div
|
||||||
|
bind:this={newMessages}
|
||||||
|
class="flex items-center py-2 text-xs transition-colors"
|
||||||
|
class:opacity-0={showFixedNewMessages}>
|
||||||
|
<div class="h-px flex-grow bg-primary"></div>
|
||||||
|
<p class="rounded-full bg-primary px-2 py-1 text-primary-content">New Messages</p>
|
||||||
|
<div class="h-px flex-grow bg-primary"></div>
|
||||||
|
</div>
|
||||||
|
{:else if type === "date"}
|
||||||
|
<Divider>{value}</Divider>
|
||||||
|
{:else}
|
||||||
|
<div in:slide class:-mt-1={!showPubkey}>
|
||||||
|
<ChannelMessage
|
||||||
|
{url}
|
||||||
|
{room}
|
||||||
|
{replyTo}
|
||||||
|
event={$state.snapshot(value as TrustedEvent)}
|
||||||
|
{showPubkey} />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
<p class="flex h-10 items-center justify-center py-20">
|
||||||
|
{#if loadingEvents}
|
||||||
|
<Spinner loading={loadingEvents}>Looking for messages...</Spinner>
|
||||||
|
{:else}
|
||||||
|
<Spinner>End of message history</Spinner>
|
||||||
|
{/if}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="chat__compose bg-base-200">
|
||||||
|
<div bind:this={parentPreview}>
|
||||||
{#if parent}
|
{#if parent}
|
||||||
<ChannelComposeParent event={parent} clear={clearParent} verb="Replying to" />
|
<ChannelComposeParent event={parent} clear={clearParent} verb="Replying to" />
|
||||||
{/if}
|
{/if}
|
||||||
{#if share}
|
{#if share}
|
||||||
<ChannelComposeParent event={share} clear={clearShare} verb="Sharing" />
|
<ChannelComposeParent event={share} clear={clearShare} verb="Sharing" />
|
||||||
{/if}
|
{/if}
|
||||||
<ChannelCompose bind:this={compose} {onSubmit} />
|
|
||||||
</div>
|
</div>
|
||||||
|
<ChannelCompose bind:this={compose} {onSubmit} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if showScrollButton}
|
{#if showScrollButton}
|
||||||
<div in:fade class="fixed bottom-14 right-4">
|
<div in:fade class="chat__scroll-down">
|
||||||
<Button class="btn btn-circle btn-neutral" onclick={scrollToBottom}>
|
<Button class="btn btn-circle btn-neutral" onclick={scrollToBottom}>
|
||||||
<Icon icon="alt-arrow-down" />
|
<Icon icon="alt-arrow-down" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#if showFixedNewMessages}
|
||||||
|
<div class="relative z-feature flex justify-center">
|
||||||
|
<div transition:fly={{duration: 200}} class="fixed top-12">
|
||||||
|
<Button class="btn btn-primary btn-xs rounded-full" onclick={scrollToNewMessages}>
|
||||||
|
New Messages
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|||||||
Reference in New Issue
Block a user