Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: channel drawer, emoji and gif picker issues #534

Merged
merged 3 commits into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/lib/components/Browse/DrawerAddCategory.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
})
</script>

<div class="flex h-full p-5">
<div class="flex lg:h-full p-5">
<div class="bg-base-200 rounded-lg w-80 md:w-[30rem] flex flex-col {classes}">
<p class="p-3 text-xl mb-5 pb-2 border-purple-500 font-semibold border-b-2">Select category</p>
<div class="flex flex-col p-3 h-full">
Expand Down
6 changes: 3 additions & 3 deletions src/lib/components/Browse/DrawerCreateChannel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,14 @@
<DrawerAddCategory bind:showAddCategory bind:categories={newChannel.category} />
{:else}
<form
class="flex h-full p-5"
class="flex lg:h-full p-5"
action="?/create-channel"
method="post"
use:enhance={({ data }) => {
isLoadingChannel = true
data.append('newChannel', JSON.stringify(newChannel))
}}>
<div class="bg-base-200 w-80 md:w-[30rem] h-full flex flex-col rounded-lg">
<div class="bg-base-200 w-80 md:w-[30rem] h-full flex flex-col rounded-lg lg:mb-0 mb-20">
<p class="p-3 text-xl mb-5 pb-2 border-purple-500 font-semibold border-b-2">
Create a new channel
</p>
Expand Down Expand Up @@ -151,7 +151,7 @@
{#if $tags && $tags.length > 0}
{#each $tags as tag}
<span
class="badge badge-md text-primary bg-gray-200 rounded-md font-semibold mx-1 cursor-pointer border-none"
class="badge badge-md text-primary bg-gray-200 rounded-md font-semibold mx-1 cursor-pointer border-none my-1"
on:click={() => addTag(tag.name)}>{tag.name}</span>
{/each}
{:else}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/Channel/Chat/DrawerChat.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@

</script>

<div class="bg-base-100 flex flex-col overflow-y-hidden w-96 md:w-full h-full rounded-lg">
<div class="bg-base-100 flex flex-col overflow-y-hidden w-72 md:w-full h-full rounded-lg">
<DropdownViewChannel bind:channel bind:showEditChannelDrawer />
<div class="flex flex-col-reverse p-3 grow overflow-y-scroll w-96">
{#each chatHistory as sender}
Expand Down
39 changes: 9 additions & 30 deletions src/lib/components/Channel/Chat/EmojiPicker.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { onMount } from 'svelte'
import FloatingMenu from './FloatingMenu.svelte'
import IconChatEmoji from '$lib/assets/icons/chat/IconChatEmoji.svelte'
import { clickOutside } from '../../../utils.js';

export let onSelect: any

Expand All @@ -28,34 +28,13 @@
}
})

const handleClickOutside = () =>{
isFocused = false
}

$: btnClass = isFocused ? "btn-primary" : "btn-neutral"

</script>

<div use:clickOutside={handleClickOutside} class="dropdown dropdown-top">
<button
bind:this={btn}
tabindex="0"
type="button"
class={"btn text-white border-none tooltip font-normal normal-case " + btnClass}
data-tip="Emoji"
>
<IconChatEmoji />
<span class="sr-only">Add emoji</span>
</button>
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<div
bind:this={container}
tabindex="0"
class={'dropdown-content menu shadow bg-base-100 rounded-box emoji-container'} />
</div>

<style global>
emoji-picker {
margin-left: -70px;
}
</style>
<FloatingMenu
id='emoji-picker'
icon={IconChatEmoji}
label="Emoji"
>
<div bind:this={container} />
</FloatingMenu>

57 changes: 57 additions & 0 deletions src/lib/components/Channel/Chat/FloatingMenu.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<script lang="ts">
import { clickOutside } from '../../../utils.js';
export let id:string = "float-menu"
export let icon:any = null
export let label:string = ""

let btn: any
let isFocused = false

const handleClickOutside = (event: any) =>{
const _id = event.target.id ||
event.target.parentElement.id ||
event.target.parentElement.parentElement.id

if(id !== _id)
isFocused = false
}

const forceClose = () => {
isFocused = false
}

$: btnClass = isFocused ? "btn-primary" : "btn-neutral"
$: dropdownClass = isFocused ? "dropdown-open" : ""
$: bottom = btn ? window.innerHeight - (btn.getBoundingClientRect().top) : 0

</script>
<button
bind:this={btn}
id={id}
type="button"
class={"btn text-white border-none tooltip font-normal normal-case " + btnClass}
data-tip={label}
on:click={() => {
isFocused = true
}}
>
<svelte:component id={id} this={icon} />
<span class="sr-only">Add emoji</span>
</button>
<div
use:clickOutside={handleClickOutside}
class={"dropdown dropdown-top " + dropdownClass}
>
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<div
style="bottom: {bottom}px"
class={'dropdown-content menu shadow !fixed right-0 z-50 floating-menu overflow-auto'}
>
<slot {forceClose} />
</div>
</div>
<style>
.floating-menu {
max-width: 100vw;
}
</style>
106 changes: 38 additions & 68 deletions src/lib/components/Channel/Chat/GifPicker.svelte
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
<script lang="ts">
import { onMount } from 'svelte'
import IconChatGif from '$lib/assets/icons/chat/IconChatGif.svelte'
import { clickOutside } from '../../../utils.js'
import FloatingMenu from './FloatingMenu.svelte'

import { get } from '../../../api.js'

export let onSelect: any

let btn: any
let isFocused = false

let gifs: { downsized_large: string; original: string; title: string }[] = []
let searched: { downsized_large: string; original: string; title: string }[] = []
let query: string = ''
Expand All @@ -20,22 +17,8 @@
const resp = await get('giphy/trending')
if (resp && Array.isArray(resp)) gifs = resp
loading = false

if (btn) {
btn.addEventListener('focus', () => {
isFocused = true
})
}
})

const handleClickOutside = () => {
isFocused = false
}

const openPicker = () => {
isFocused = true
}

const onSearch = async (evt: any) => {
query = evt.target.value
loading = true
Expand All @@ -44,66 +27,53 @@
if (resp && Array.isArray(resp)) searched = resp
}

$: btnClass = isFocused ? 'btn-primary' : 'btn-neutral'
$: dropdownClass = isFocused ? 'dropdown-open' : ''
$: list = query ? searched : gifs
</script>

<div
use:clickOutside={handleClickOutside}
class={"dropdown dropdown-top " + dropdownClass}
<FloatingMenu
let:forceClose id="gif-picker"
icon = {IconChatGif}
label="GIF"
>
<button
bind:this={btn}
type="button"
class={'btn text-white border-none tooltip font-normal normal-case ' + btnClass}
data-tip="GIF"
on:click={openPicker}>
<IconChatGif />
<span class="sr-only">Add GIF</span>
</button>
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<div class={'dropdown-content menu shadow bg-base-100'}>
<div class="gif-picker bg-base-300 flex flex-col rounded-md px-2">
<div class="m-2">
<input
type="text"
placeholder="Search here"
class="input input-bordered input-sm w-full max-w-xs"
on:input={onSearch} />
</div>

{#if loading}
<div class="flex items-center justify-center py-4 w-full">
<span class="loading loading-dots loading-sm" />
</div>
{:else if list.length}
<div class="grid grid-cols-4 gap-2 flex-1 overflow-auto mt-2">
{#each list as gif}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
class="border cursor-pointer"
on:click={() => {
onSelect(gif.downsized_large)
isFocused = false
}}>
<img src={gif.downsized_large} alt="gif" class="w-full" />
</div>
{/each}
</div>
{:else}
<div class="flex items-center justify-center py-4 w-full">
<span class="text-sm text-neutral">No Items Found</span>
</div>
{/if}
<div class="gif-picker bg-base-300 flex flex-col rounded-md px-2">
<div class="m-2">
<input
type="text"
placeholder="Search here"
class="input input-bordered input-sm w-full max-w-xs"
on:input={onSearch} />
</div>

{#if loading}
<div class="flex items-center justify-center py-4 w-full">
<span class="loading loading-dots loading-sm" />
</div>
{:else if list.length}
<div class="grid grid-cols-4 gap-2 flex-1 overflow-auto mt-2">
{#each list as gif}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div
class="border cursor-pointer"
on:click={() => {
onSelect(gif.downsized_large)
forceClose()
}}>
<img src={gif.downsized_large} alt="gif" class="w-full" />
</div>
{/each}
</div>
{:else}
<div class="flex items-center justify-center py-4 w-full">
<span class="text-sm text-neutral">No Items Found</span>
</div>
{/if}
</div>
</div>
</FloatingMenu>

<style global>
.gif-picker {
margin-left: -130px;
width: 350px;
height: 400px;
max-width: 100%;
}
</style>
2 changes: 1 addition & 1 deletion src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ export const getAudioIndicator = (
export const clickOutside = (element: any, callbackFunction: any) => {
const onClick = (event: any) => {
if (!element.contains(event.target)) {
callbackFunction();
callbackFunction(event);
}
}

Expand Down