-
Notifications
You must be signed in to change notification settings - Fork 16
/
ChatMessageDetails.svelte
144 lines (134 loc) · 6.22 KB
/
ChatMessageDetails.svelte
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<script lang="ts">
import { fade } from "svelte/transition";
import QrCode from "svelte-qrcode";
import { darkMode, permissionLevel } from "./stores";
import { ChatMessage, PermissionLevel, UserRole } from "./proto/jungletv_pb";
import { buildMonKeyURL, copyToClipboard } from "./utils";
import { createEventDispatcher } from "svelte";
import { openUserProfile } from "./profile_utils";
export let msg: ChatMessage;
export let allowReplies: boolean;
let copied = false;
const dispatch = createEventDispatcher();
let isChatModerator = false;
$: isChatModerator = $permissionLevel == PermissionLevel.ADMIN;
let topOffset = isChatModerator ? -208 : -168;
$: topOffset = isChatModerator ? -208 : -168;
function openProfile() {
openUserProfile(msg.getUserMessage().getAuthor().getAddress());
}
function openExplorer() {
window.open(
"https://creeper.banano.cc/account/" + msg.getUserMessage().getAuthor().getAddress(),
"",
"noopener"
);
}
async function copyAddress() {
await copyToClipboard(msg.getUserMessage().getAuthor().getAddress());
copied = true;
}
function keyDown(ev: KeyboardEvent) {
if (ev.key == "Escape") {
dispatch("mouseLeft");
}
}
// this is a workaround
// stuff like dark: and hover: doesn't work in the postcss @apply
// https://github.com/tailwindlabs/tailwindcss/discussions/2917
const commonButtonClasses =
"text-purple-700 dark:text-purple-500 px-1.5 py-1 rounded hover:shadow-sm " +
"hover:bg-gray-100 dark:hover:bg-gray-800 outline-none focus:outline-none " +
"ease-linear transition-all duration-150 cursor-pointer" +
"focus:bg-gray-100 dark:focus:bg-gray-800";
</script>
<div
class="absolute w-full max-w-md left-0"
style="top: {topOffset}px"
transition:fade|local={{ duration: 200 }}
on:keydown={keyDown}
>
<div class="bg-gray-200 dark:bg-black rounded flex flex-col shadow-md">
<div class="flex flex-row px-2 pt-2 overflow-x-hidden max-w-full" on:mouseenter={() => dispatch("mouseLeft")}>
<img
src={buildMonKeyURL(msg.getUserMessage().getAuthor().getAddress())}
alt=" "
title="monKey for this user's address"
class="h-20 w-20"
/>
<div class="flex-grow overflow-x-hidden">
{#if msg.getUserMessage().getAuthor().hasNickname()}
<span class="font-semibold text-md whitespace-nowrap"
>{msg.getUserMessage().getAuthor().getNickname()}</span
>
<br />
{/if}
<span class="font-mono text-md">
{msg.getUserMessage().getAuthor().getAddress().substr(0, 14)}
</span>
{#if msg.getUserMessage().getAuthor().getRolesList().includes(UserRole.MODERATOR)}
<br />
<span class="text-sm">
<i class="fas fa-shield-alt text-purple-700 dark:text-purple-500" title="" />
Chat moderator
</span>
{:else if msg.getUserMessage().getAuthor().getRolesList().includes(UserRole.CURRENT_ENTRY_REQUESTER)}
<br />
<span class="text-sm">
<i class="fas fa-coins text-green-700 dark:text-green-500" title="" />
Media requester
</span>
{:else if msg.getUserMessage().getAuthor().getRolesList().includes(UserRole.TIER_1_REQUESTER)}
<br />
<span class="text-sm text-blue-600 dark:text-blue-400">Tier 1 media requester</span>
{:else if msg.getUserMessage().getAuthor().getRolesList().includes(UserRole.TIER_2_REQUESTER)}
<br />
<span class="text-sm text-yellow-600 dark:text-yellow-200">Tier 2 media requester</span>
{:else if msg.getUserMessage().getAuthor().getRolesList().includes(UserRole.TIER_3_REQUESTER)}
<br />
<span class="text-sm text-green-500 dark:text-green-300">Tier 3 media requester</span>
{/if}
</div>
<QrCode
value={"ban:" + msg.getUserMessage().getAuthor().getAddress()}
size="80"
padding="0"
background={$darkMode ? "#000000" : "#e5e7eb"}
color={$darkMode ? "#e5e7eb" : "#000000"}
/>
</div>
<div class="grid grid-cols-6 gap-2 place-items-center px-2 pb-2">
{#if isChatModerator}
<button class="{commonButtonClasses} col-span-2" on:click={() => dispatch("delete")}>
<i class="fas fa-trash" /> Delete
</button>
<button class="{commonButtonClasses} col-span-2" on:click={() => dispatch("history")}>
<i class="fas fa-history" /> History
</button>
<button class="{commonButtonClasses} col-span-2" on:click={() => dispatch("changeNickname")}>
<i class="fas fa-edit" /> Nickname
</button>
{/if}
<button
class="{commonButtonClasses} {isChatModerator ? 'col-span-3' : 'col-span-6'}"
on:click={openProfile}
>
<i class="fas fa-id-card" /> Profile
</button>
{#if isChatModerator}
<button class="{commonButtonClasses} col-span-3" on:click={() => openExplorer()}>
<i class="fas fa-search-dollar" /> Explorer
</button>
{/if}
{#if allowReplies}
<button class="{commonButtonClasses} col-span-3" on:click={() => dispatch("reply")}>
<i class="fas fa-reply" /> Reply
</button>
{/if}
<button class="{commonButtonClasses} {allowReplies ? 'col-span-3' : 'col-span-6'}" on:click={copyAddress}>
<i class="fas fa-copy" />
{copied ? "Copied!" : "Copy address"}
</button>
</div>
</div>
</div>