Skip to content
Draft
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
176 changes: 162 additions & 14 deletions docs/YOUTUBE_ACTIONS.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const safelistSelectors = [
'body',
'stroke-primary',
'mode-dark',
'line-through',
// Components with custom color prop might need its color to be whitelisted too
'bg-blue-500',
'hover:bg-blue-400'
Expand Down
31 changes: 20 additions & 11 deletions src/components/Hyperchat.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
chatUserActionsItems,
ChatUserActions
} from '../ts/chat-constants';
import { isAllEmoji, isChatMessage, isPrivileged, responseIsAction } from '../ts/chat-utils';
import { buildDeletedObj, isAllEmoji, isChatMessage, isPrivileged, responseIsAction } from '../ts/chat-utils';
import { handleReplyThreadResponse } from '../ts/chat-actions';
import Button from 'smelte/src/components/Button';
import {
Expand Down Expand Up @@ -216,14 +216,15 @@
};

const onDelete = (deletion: Ytc.ParsedDeleted) => {
messageActions.some((action) => {
const changed = messageActions.some((action) => {
if (isWelcome(action)) return false;
if (action.message.messageId === deletion.messageId) {
action.deleted = { replace: deletion.replacedMessage };
action.deleted = buildDeletedObj(deletion, action.message.message);
return true;
}
return false;
});
if (changed) messageActions = messageActions;
};

const onChatAction = (action: Chat.Actions, isInitial = false) => {
Expand Down Expand Up @@ -303,6 +304,12 @@
else document.body.classList.remove('bg-ytdark-50');
};

const removesAuthorMessages = (action: ChatUserActions): boolean => {
return action === ChatUserActions.BLOCK ||
action === ChatUserActions.REPORT_USER ||
action === ChatUserActions.HIDE_USER;
};

const onPortMessage = (response: Chat.BackgroundResponse) => {
if (responseIsAction(response)) {
onChatAction(response);
Expand All @@ -320,20 +327,22 @@
$ytDark = response.dark;
break;
case 'chatUserActionResponse':
if (response.success && response.action === ChatUserActions.DELETE_MESSAGE) {
onDelete({
messageId: response.message.messageId,
replacedMessage: [],
pending: true
});
break;
}
$alertDialog = {
title: response.success ? 'Success!' : 'Error',
message: chatUserActionsItems.find(v => v.value === response.action)
?.messages[response.success ? 'success' : 'error'] ?? '',
color: response.success ? 'primary' : 'error'
};
if (response.success) {
if (response.action === ChatUserActions.DELETE_MESSAGE) {
onDelete({
messageId: response.message.messageId,
replacedMessage: [{ text: '[message retracted]' }]
});
break;
}
if (!removesAuthorMessages(response.action)) break;
messageActions = messageActions.filter(
(a) => {
if (isWelcome(a)) return true;
Expand Down Expand Up @@ -465,7 +474,7 @@
{#if $enableStickySuperchatBar}
<StickyBar />
{/if}
<div class="w-full min-h-0 flex justify-end flex-col relative">
<div class="w-full min-h-0 flex-1 flex justify-end flex-col relative">
<div bind:this={div} on:scroll={checkAtBottom} class="content overflow-y-scroll">
<div style="height: {topBarSize}px;" />
{#each messageActions as action (action.message.messageId)}
Expand Down
47 changes: 37 additions & 10 deletions src/components/Message.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,17 @@
});
$: nameColorClass = generateNameColorClass(member, moderator, owner, forceDark);

$: if (deleted != null) {
message.message = deleted.replace;
let showOriginal = false;
$: displayRuns = deleted != null && !showOriginal ? deleted.replace : message.message;
// If showing original text, swap the first text run to 'hide'.
let toggleLabelRuns: Ytc.ParsedRun[] | undefined;
$: {
let swapped = !showOriginal;
toggleLabelRuns = deleted?.viewOriginalText?.map((r) => {
if (swapped || r.type !== 'text') return r;
swapped = true;
return { ...r, text: 'Hide deleted message' };
});
}
$: displayAuthorName = formatAuthorName(message.author.name);

Expand All @@ -71,10 +80,14 @@

$: isSelf = message.author.id === $selfChannelId;
$: visibleActions = chatUserActionsItems.filter((d) => {
if (isSelf) {
return d.value === ChatUserActions.DELETE_MESSAGE && message.params != null;
if (d.value === ChatUserActions.DELETE_MESSAGE) {
return (isSelf || message.canDelete) && message.params != null && deleted == null;
}
return d.value !== ChatUserActions.DELETE_MESSAGE;
if (isSelf) return false;
if (message.params == null) {
return d.value === ChatUserActions.BLOCK || d.value === ChatUserActions.REPORT_USER;
}
return true;
});
$: menuItems = visibleActions.map((d) => ({
icon: d.icon,
Expand All @@ -92,13 +105,13 @@
</script>

<!-- svelte-ignore a11y-mouse-events-have-key-events -->
<div
<div
class="inline-flex flex-row gap-2 break-words w-full overflow-visible"
>
{#if !hideName && $showProfileIcons}
<a
href={message.author.url}
class="flex-shrink-0 {message.author.url ? 'cursor-pointer' : 'cursor-auto'}"
class="flex-shrink-0 {message.author.url ? 'cursor-pointer' : 'cursor-auto'} {deleted != null ? 'opacity-50' : ''}"
target="_blank"
>
<img
Expand All @@ -108,7 +121,7 @@
/>
</a>
{/if}
<div>
<div class={deleted != null ? 'opacity-50' : ''}>
{#if !hideName}
<span
class="text-xs mr-1 text-gray-700 dark:text-gray-600 align-middle"
Expand Down Expand Up @@ -177,12 +190,26 @@
</span>
{/if}
<MessageRun
runs={message.message}
runs={displayRuns}
{forceDark}
deleted={deleted != null}
{forceTLColor}
class={message.membershipGiftRedeem ? 'text-gray-700 dark:text-gray-600 italic font-medium' : ''}
class="{message.membershipGiftRedeem ? 'text-gray-700 dark:text-gray-600 italic font-medium' : ''} {deleted?.pending || showOriginal ? 'line-through' : ''}"
/>
{#if deleted?.viewOriginalText}
<button
type="button"
on:click={() => (showOriginal = !showOriginal)}
class="ml-1 align-middle text-xs cursor-pointer text-deleted-light dark:text-deleted-dark bg-transparent border-0 p-0"
>
<MessageRun
runs={toggleLabelRuns}
{forceDark}
{forceTLColor}
class="underline cursor-pointer"
/>
</button>
{/if}
{#if message.membershipGiftRedeem}
<svg
height="1em"
Expand Down
19 changes: 19 additions & 0 deletions src/components/ReportBanDialog.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import type { ChatReportUserOptions } from '../ts/chat-constants';
import {
reportDialog,
chatActionOptionDialog,
alertDialog
} from '../ts/storage';
import Dialog from './common/Dialog.svelte';
import type { Writable } from 'svelte/store';
import RadioGroupStore from './common/RadioGroupStore.svelte';
import Button from 'smelte/src/components/Button';
$: optionStore = $reportDialog?.optionStore as Writable<ChatReportUserOptions>;
$: actionOptionStore = $chatActionOptionDialog?.optionStore as Writable<string>;
</script>

<Dialog active={Boolean($reportDialog)} class="max-w-full max-h-full" style="height: 500px; width: 500px;">
Expand All @@ -29,6 +31,23 @@
</div>
</Dialog>

<Dialog active={Boolean($chatActionOptionDialog)} class="max-w-full max-h-full" style="height: 360px; width: 420px;">
<svelte:fragment slot="title">{$chatActionOptionDialog?.title}</svelte:fragment>
<div>
<RadioGroupStore
store={actionOptionStore}
items={$chatActionOptionDialog?.items ?? []}
vertical
/>
</div>
<div slot="actions">
<Button on:click={() => {
$chatActionOptionDialog?.callback($actionOptionStore);
$chatActionOptionDialog = null;
}} color="error" disabled={!$actionOptionStore}>{$chatActionOptionDialog?.confirmText}</Button>
</div>
</Dialog>

<Dialog active={Boolean($alertDialog)} noCloseButton>
<svelte:fragment slot="title">{$alertDialog?.title}</svelte:fragment>
<div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/common/Menu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
class={menuClasses}
transition:fade={{ duration: 150 }}
bind:this={listDiv}
style="max-width: 20em; font-size: 0.9em; {offsetYStyle}"
style="max-width: 20em; font-size: 1em; {offsetYStyle}"
>
<List
select
Expand All @@ -98,7 +98,7 @@
on:click={() => { onItemClick(item); }}
style="padding: 0.5em 1em"
>
<Icon class="pr-6">
<Icon class="pr-2">
{item.icon}
</Icon>
<span>{item.text}</span>
Expand Down
Loading
Loading