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
4 changes: 2 additions & 2 deletions apps/desktop/src/components/app/ChatApp.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@
{:else}
<div class="flex flex-1 items-center justify-center">
<div class="text-center">
<p class="text-muted text-lg">チャンネルを選択</p>
<p class="text-muted text-lg">Select a Channel</p>
<p class="text-muted mt-1 text-sm opacity-60">
左のサイドバーからチャンネルを選んでください
Choose a channel from the sidebar
</p>
</div>
</div>
Expand Down
8 changes: 4 additions & 4 deletions apps/desktop/src/components/app/OrganizationSidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,25 @@
<aside class="border-subtle bg-base-200 flex h-full w-72 flex-col border-r">
<!-- Organization header -->
<header
class="border-subtle flex items-center justify-between border-b px-4 py-3"
class="border-subtle flex items-center justify-between border-b px-4 py-4"
>
<div class="min-w-0 flex-1">
<h1 class="truncate font-semibold tracking-tight">
{organization?.name ?? "Loading..."}
</h1>
</div>
<div class="flex items-center gap-1">
<div class="flex items-center gap-2">
<a
href="/orgs/{organizationId}/settings"
class="btn btn-ghost btn-sm btn-square hover-highlight"
title="組織設定"
title="Organization Settings"
>
<Settings class="text-muted size-4" />
</a>
<a
href="/"
class="btn btn-ghost btn-sm btn-square hover-highlight"
title="組織を切り替え"
title="Switch Organization"
>
<ArrowLeftRight class="text-muted size-4" />
</a>
Expand Down
23 changes: 14 additions & 9 deletions apps/desktop/src/components/channels/Channel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,24 @@
() => selectedChannelId,
() => organizationId,
);

function autofocus(node: HTMLElement) {
node.focus();
}
</script>

<div class="flex h-full flex-col">
<!-- Channel header -->
<header
class="border-subtle flex items-center justify-between border-b px-6 py-4"
>
<div class="flex items-center gap-3">
<Hash class="size-5 opacity-50" />
<div class="flex items-center gap-4">
<Hash class="size-5 opacity-60" />
<h1 class="text-base font-semibold">
{controller.selectedChannel.data?.name ?? "..."}
</h1>
{#if controller.selectedChannel.data?.description}
<span class="hidden text-sm opacity-40 sm:inline">
<span class="hidden text-sm opacity-60 sm:inline">
— {controller.selectedChannel.data.description}
</span>
{/if}
Expand All @@ -44,10 +48,11 @@
>
<input
type="text"
placeholder="メッセージを検索..."
class="input input-sm input-bordered bg-base-200 w-56 pr-8 text-sm transition-all duration-150 focus:w-64"
placeholder="Search messages..."
class="input input-sm input-bordered bg-base-200 w-56 pr-8 text-sm transition-all duration-200 focus:w-64"
bind:value={controller.searchQuery}
onkeydown={(e) => e.key === "Enter" && controller.handleSearch()}
use:autofocus
/>
{#if controller.isSearching}
<span
Expand All @@ -57,20 +62,20 @@
</div>
{/if}
<button
class="btn btn-ghost btn-sm btn-square transition-all duration-150"
title="検索"
class="btn btn-ghost btn-sm btn-square transition-all duration-200"
title="Search"
onclick={() => (controller.showSearch = !controller.showSearch)}
>
<Search
class="size-5 opacity-50 transition-opacity duration-150 hover:opacity-80"
class="size-5 opacity-60 transition-opacity duration-200 hover:opacity-80"
/>
</button>
</div>
</header>

<!-- Search results -->
{#if controller.searchResults.length > 0}
<div class="border-subtle bg-base-200/50 border-b p-2">
<div class="border-subtle bg-base-200/50 border-b p-4">
<SearchResults
results={controller.searchResults}
onResultClick={controller.handleResultClick}
Expand Down
20 changes: 10 additions & 10 deletions apps/desktop/src/components/channels/ChannelList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
<div class="flex h-full flex-col">
<!-- Channels section -->
<section class="flex-1 overflow-y-auto">
<header class="flex items-center justify-between px-3 py-2">
<header class="flex items-center justify-between px-4 py-2">
<span class="text-muted text-xs font-medium tracking-wider uppercase">
Channels
</span>
Expand All @@ -59,7 +59,7 @@
<a
href={`/orgs/${organizationId}/chat/${channel.id}`}
class={[
"group flex items-center gap-2 rounded px-2 py-1.5 text-sm transition-colors",
"group flex items-center gap-2 rounded px-2 py-2 text-sm transition-colors duration-200",
active
? "bg-primary/15 text-primary"
: "text-base-content/80 hover:bg-base-300 hover:text-base-content",
Expand All @@ -84,28 +84,28 @@
</a>
{/each}
{:else}
<div class="text-muted px-2 py-4 text-center text-sm">
読み込み中...
<div class="text-muted px-2 py-4 text-center text-sm opacity-60">
Loading...
</div>
{/if}

{#if channels.data?.length === 0}
<div class="text-muted px-2 py-4 text-center text-sm">
チャンネルがありません
<div class="text-muted px-2 py-4 text-center text-sm opacity-60">
No channels
</div>
{/if}
</nav>
</section>

<!-- DM section -->
<section class="border-subtle border-t">
<header class="flex items-center justify-between px-3 py-2">
<header class="flex items-center justify-between px-4 py-2">
<span class="text-muted text-xs font-medium tracking-wider uppercase">
Direct Messages
</span>
<button
class="btn btn-ghost btn-xs btn-square"
title="新しいDM"
title="New DM"
onclick={() => (showUserSearch = !showUserSearch)}
>
<Plus class="text-muted size-4" />
Expand All @@ -132,10 +132,10 @@
<footer class="border-subtle border-t p-2">
<a
href={`/orgs/${organizationId}/personalization`}
class="text-muted hover:bg-base-300 hover:text-base-content flex items-center gap-2 rounded px-2 py-1.5 text-sm transition-colors"
class="text-muted hover:bg-base-300 hover:text-base-content flex items-center gap-2 rounded px-2 py-2 text-sm transition-colors duration-200"
>
<User class="size-4" />
<span>個人設定</span>
<span>Settings</span>
</a>
</footer>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@

<button
class="btn btn-ghost btn-xs btn-square"
title="新しいチャンネル"
title="New channel"
onclick={() => {
modalManager.dispatch(createChannelModalContent);
}}
Expand All @@ -58,17 +58,17 @@
>
<input
type="text"
placeholder="チャンネル名"
placeholder="Channel name"
class="input input-bordered"
bind:value={newChannelName}
/>
{#if disabled}
<button type="submit" class="btn btn-primary btn-sm" disabled>
作成中...
Creating...
<span class="loading loading-spinner"></span>
</button>
{:else}
<button type="submit" class="btn btn-primary btn-sm">作成</button>
<button type="submit" class="btn btn-primary btn-sm">Create</button>
{/if}
</form>
{/snippet}
8 changes: 7 additions & 1 deletion apps/desktop/src/components/chat/EmojiButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,10 @@
Button to toggle the emoji palette.
Displays a smiling face emoji icon.
-->
<button class="btn btn-secondary self-end" {onclick}>😀</button>
<button
class="btn btn-ghost btn-sm self-end"
{onclick}
aria-label="Open emoji picker"
>
😀
</button>
9 changes: 6 additions & 3 deletions apps/desktop/src/components/chat/EmojiPalette.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import { Picker } from "emoji-picker-element";
import type { EmojiClickEvent } from "emoji-picker-element/shared";

interface Props {
onClose: () => void;
Expand Down Expand Up @@ -49,16 +50,18 @@

const emojiPicker = document.querySelector("emoji-picker");

emojiPicker?.addEventListener("emoji-click", (event) => {
const handleEmojiClick = (event: EmojiClickEvent) => {
const emoji = event.detail.unicode;
if (!emoji) return;
onEmojiSelected(emoji);
});
};

emojiPicker?.addEventListener("emoji-click", handleEmojiClick);

return () => {
document.removeEventListener("click", handleClickOutside);
if (emojiPicker) {
emojiPicker.removeEventListener("emoji-click", () => {});
emojiPicker.removeEventListener("emoji-click", handleEmojiClick);
}
};
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
-->
{#if files.length > 0}
<div class="space-y-2">
<h4 class="text-base-content/70 text-sm font-medium">添付ファイル:</h4>
<h4 class="text-base-content/70 text-sm font-medium">Attached Files:</h4>
<div class="grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-4">
{#each files as file, index (file.name)}
<FilePreview
Expand Down
18 changes: 12 additions & 6 deletions apps/desktop/src/components/chat/MessageDropdownContent.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,40 @@
isPinned,
isOwnMessage = false,
}: Props = $props();

function handleDelete() {
if (window.confirm("Are you sure you want to delete this message?")) {
onDelete?.();
}
}
</script>

<ul
class="menu dropdown-content bg-base-100 absolute z-[1] w-40 rounded-md border p-2 shadow"
>
<li>
<button onclick={onReply}>返信</button>
<button onclick={onReply}>Reply</button>
</li>
<li>
<button onclick={onAddReaction}>リアクションを付ける</button>
<button onclick={onAddReaction}>Add Reaction</button>
</li>
<li>
<button onclick={onShowReactions}>リアクションを表示</button>
<button onclick={onShowReactions}>Show Reactions</button>
</li>
<li>
<button onclick={onPin}>
{isPinned ? "ピン解除" : "ピン留め"}
{isPinned ? "Unpin" : "Pin"}
</button>
</li>
{#if isOwnMessage}
{#if onEdit}
<li>
<button onclick={onEdit}>編集</button>
<button onclick={onEdit}>Edit</button>
</li>
{/if}
{#if onDelete}
<li>
<button class="text-error" onclick={onDelete}>削除</button>
<button class="text-error" onclick={handleDelete}>Delete</button>
</li>
{/if}
{/if}
Expand Down
12 changes: 7 additions & 5 deletions apps/desktop/src/components/chat/MessageInput.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@
<!-- Reply banner -->
{#if replyingTo}
<div
class="border-subtle bg-base-200/50 flex items-center gap-2 border-b px-4 py-2 text-sm"
class="border-subtle bg-base-200/50 flex items-center gap-2 border-b px-4 py-3 text-sm"
>
<span class="text-muted">返信先:</span>
<span class="text-muted opacity-60">Replying to:</span>
<span class="text-primary font-medium">{replyingTo.author}</span>
<span class="text-muted flex-1 truncate">{replyingTo.content}</span>
<span class="text-muted flex-1 truncate opacity-60"
>{replyingTo.content}</span
>
<button
class="btn btn-ghost btn-xs btn-square"
onclick={() => (replyingTo = null)}
Expand Down Expand Up @@ -75,7 +77,7 @@
{/if}

<!-- Input area -->
<div class="flex items-end gap-2 p-3">
<div class="flex items-end gap-2 p-4">
<div class="flex-1">
<MessageTextarea
bind:value={controller.messageContent}
Expand All @@ -87,7 +89,7 @@
/>
</div>

<div class="flex items-center gap-1">
<div class="flex items-center gap-2">
<EmojiButton
onclick={(e) => {
e.stopPropagation();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ export class MessageInputController {
await this.api.sendMessageMutation.run({
channelId: this.channelId,
content: this.messageContent.trim() || "",
author: this.api.identity.data?.name || "unregistered",
parentId: this.replyingTo?.id ?? undefined,
attachments,
voteId,
Expand Down
Loading