Skip to content

Commit

Permalink
feat: w2g chat
Browse files Browse the repository at this point in the history
  • Loading branch information
ThaUnknown committed Aug 25, 2024
1 parent cbcc021 commit 67d19eb
Show file tree
Hide file tree
Showing 9 changed files with 433 additions and 159 deletions.
3 changes: 1 addition & 2 deletions common/modules/sections.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ function createSections () {
{ title: 'Romance', variables: { sort: 'TRENDING_DESC', genre: 'Romance' } },
{ title: 'Action', variables: { sort: 'TRENDING_DESC', genre: 'Action' } },
{ title: 'Adventure', variables: { sort: 'TRENDING_DESC', genre: 'Adventure' } },
{ title: 'Fantasy', variables: { sort: 'TRENDING_DESC', genre: 'Fantasy' } },
{ title: 'Comedy', variables: { sort: 'TRENDING_DESC', genre: 'Comedy' } }
{ title: 'Fantasy', variables: { sort: 'TRENDING_DESC', genre: 'Fantasy' } }
]
}
2 changes: 1 addition & 1 deletion common/views/Player/MediaHandler.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@
}
function setDiscordRPC (np = nowPlaying.value) {
const w2g = state.value
const w2g = state.value?.code
const details = [np.title, np.episodeTitle].filter(i => i).join(' - ') || undefined
const activity = {
details,
Expand Down
4 changes: 2 additions & 2 deletions common/views/Player/Player.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
const emit = createEventDispatcher()
w2gEmitter.on('playerupdate', ({ detail }) => {
w2gEmitter.on('playerupdate', detail => {
currentTime = detail.time
paused = detail.paused
})
w2gEmitter.on('setindex', ({ detail }) => {
w2gEmitter.on('setindex', detail => {
playFile(detail)
})
Expand Down
103 changes: 86 additions & 17 deletions common/views/WatchTogether/Lobby.svelte
Original file line number Diff line number Diff line change
@@ -1,19 +1,94 @@
<script>
import { click } from '@/modules/click.js'
import IPC from '@/modules/ipc.js'
import { ExternalLink, User } from 'lucide-svelte'
export let peers
import User from './User.svelte'
import Message from './Message.svelte'
import { SendHorizontal, DoorOpen, UserPlus } from 'lucide-svelte'
export let invite
export let cleanup
export let state
function cleanup () {
state.value?.destroy()
state.value = null
}
$: peers = $state?.peers
$: messages = $state?.messages
/**
* @param {{ message: string, user: import('@/modules/al.d.ts').Viewer | {id: string }, type: 'incoming' | 'outgoing', date: Date }[]} messages
*/
function groupMessages (messages) {
if (!messages?.length) return []
const grouped = []
for (const { message, user, type, date } of messages.slice(-50)) {
const last = grouped[grouped.length - 1]
if (last && last.user.id === user.id) {
last.messages.push(message)
} else {
grouped.push({ user, messages: [message], type, date })
}
}
return grouped
}
let message = ''
let rows = 1
function sendMessage () {
if (message) {
state.value.message(message.trim())
message = ''
rows = 1
}
}
function checkInput (e) {
if (e.key === 'Enter' && e.shiftKey === false && message) {
sendMessage()
} else {
rows = message.split('\n').length || 1
}
}
</script>
<div class='d-flex flex-column py-20 root container card'>
<div class='d-flex align-items-center w-full'>
<h1 class='font-weight-bold mr-auto'>Lobby</h1>
<button class='btn btn-success btn-lg ml-20' type='button' use:click={invite}>Invite To Lobby</button>
<button class='btn btn-danger ml-20 btn-lg' type='button' use:click={cleanup}>Leave lobby</button>
<div class='d-flex flex-column root w-full position-relative px-md-20 h-full overflow-hidden'>
<div class='d-flex flex-md-row flex-column-reverse w-full h-full pt-20'>
<div class='d-flex flex-column justify-content-end overflow-hidden flex-grow-1 px-20 pb-md-20'>
{#each groupMessages($messages) as { user, messages, type, date }}
<Message time={date} {user} {messages} {type} />
{/each}
<div class='d-flex mt-20'>
<button class='btn text-danger d-flex mt-auto align-items-center justify-content-center mr-10 border-0 px-0 shadow-none' type='button' use:click={cleanup} style='height: 3.75rem !important; width: 3.75rem !important;'>
<DoorOpen size='1.8rem' strokeWidth={2.5} />
</button>
<button class='btn text-success d-flex mt-auto align-items-center justify-content-center mr-20 border-0 px-0 shadow-none' type='button' use:click={invite} style='height: 3.75rem !important; width: 3.75rem !important;'>
<UserPlus size='1.8rem' strokeWidth={2.5} />
</button>
<textarea
bind:value={message}
class='form-control h-auto mt-20 px-15 d-flex align-items-center justify-content-center line-height-normal w-auto flex-grow-1 shadow-0'
{rows}
style='resize: none; min-height: 0 !important'
autocomplete='off'
maxlength='2048'
placeholder='Message' on:keyup={checkInput} />
<button class='btn d-flex mt-auto align-items-center justify-content-center ml-20 border-0 px-0 shadow-none' type='button' use:click={sendMessage} style='height: 3.75rem !important; width: 3.75rem !important;'>
<SendHorizontal size='1.8rem' strokeWidth={2.5} />
</button>
</div>
</div>
<div class='d-flex flex-column w-350 mw-full px-20'>
{#if peers}
<div class='font-size-20 font-weight-bold pl-5 pb-10'>
{Object.values($peers).length} Member(s)
</div>
{#each Object.values($peers) as user}
<User {user} />
{/each}
{/if}
</div>
</div>
{#each Object.values(peers) as peer}
<!-- {#each Object.values($peers) as peer}
<div class='d-flex align-items-center pb-10'>
{#if peer.user?.avatar?.medium}
<img src={peer.user?.avatar?.medium} alt='avatar' class='w-50 h-50 img-fluid rounded' />
Expand All @@ -25,11 +100,5 @@
<span class='pointer text-primary d-flex align-items-center' use:click={() => IPC.emit('open', 'https://anilist.co/user/' + peer.user?.name)}><ExternalLink size='2.5rem' /></span>
{/if}
</div>
{/each}
{/each} -->
</div>

<style>
.anon {
font-size: 5rem;
}
</style>
47 changes: 47 additions & 0 deletions common/views/WatchTogether/Message.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<script>
/** @type {import("d:/Webdevelopment/miru/common/modules/al").Viewer | {}} */
export let user = {}
/** @type {string[]} */
export let messages = []
/** @type {Date} */
export let time
/** @type {'incoming' | 'outgoing'} */
export let type = 'incoming'
const incoming = type === 'incoming'
</script>

<div class='message d-flex flex-row mt-15' class:flex-row={incoming} class:flex-row-reverse={!incoming}>
<img src={user.avatar?.medium || 'https://s4.anilist.co/file/anilistcdn/user/avatar/large/default.png'} alt='ProfilePicture' class='w-50 h-50 rounded-circle p-5 mt-auto' />
<div class='d-flex flex-column px-10 align-items-start flex-auto' class:align-items-start={incoming} class:align-items-end={!incoming}>
<div class='pb-5 d-flex flex-row align-items-center px-5'>
<div class='font-weight-bold font-size-18 line-height-normal'>
{user.name || 'Anonymous'}
</div>
<div class='text-muted pl-10 font-size-12 line-height-normal'>
{time.toLocaleTimeString()}
</div>
</div>
{#each messages as message}
<div class='bg-dark-light py-10 px-15 rounded-top rounded-right mb-5 select-all pre-wrap' style='max-width: calc(100% - 10rem)'
class:bg-dark-light={incoming} class:bg-accent={!incoming}
class:rounded-right={incoming} class:rounded-left={!incoming}>
{message}
</div>
{/each}
</div>
</div>

<style>
.message {
--base-border-radius: 1.3rem;
}
.bg-accent {
background-color: var(--accent-color);
}
.flex-auto {
flex: auto;
}
</style>
20 changes: 20 additions & 0 deletions common/views/WatchTogether/User.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<script>
import { click } from '@/modules/click.js'
import IPC from '@/modules/ipc.js'
import { ExternalLink } from 'lucide-svelte'
/** @type {import("d:/Webdevelopment/miru/common/modules/al").Viewer | {}} */
export let user = {}
</script>

<div class='d-flex align-items-center pb-10'>
<img src={user.avatar?.medium || 'https://s4.anilist.co/file/anilistcdn/user/avatar/large/default.png'} alt='ProfilePicture' class='w-50 h-50 rounded-circle p-5 mt-auto' />
<div class='font-size-18 line-height-normal pl-5'>
{user.name || 'Anonymous'}
</div>
{#if user.name}
<span class='pointer text-primary d-flex align-items-center ml-auto' use:click={() => IPC.emit('open', 'https://anilist.co/user/' + user.name)}>
<ExternalLink size='2rem' />
</span>
{/if}
</div>
Loading

0 comments on commit 67d19eb

Please sign in to comment.