restyle right panel (#491)

Co-authored-by: BlowaterNostr <blowater.nostr@proton.me>
This commit is contained in:
Bob 2024-07-08 15:01:39 +08:00 committed by GitHub
parent 4f9f0186e4
commit 0ec95d4bc2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 253 additions and 244 deletions

View File

@ -1,14 +1,9 @@
import { Database_View, EventMark, EventMarker, EventsAdapter, Indices, RelayRecorder } from "../database.ts"; import { Database_View, EventMark, EventMarker, EventsAdapter, Indices, RelayRecorder } from "../database.ts";
import { EventBus } from "../event-bus.ts"; import { EventBus } from "../event-bus.ts";
import { import { NostrAccountContext, NostrEvent, NostrKind, prepareNormalNostrEvent } from "@blowater/nostr-sdk";
InMemoryAccountContext,
NostrAccountContext,
NostrEvent,
NostrKind,
prepareNormalNostrEvent,
} from "@blowater/nostr-sdk";
import { UI_Interaction_Event } from "./app_update.tsx"; import { UI_Interaction_Event } from "./app_update.tsx";
import { Profile_Nostr_Event } from "../nostr.ts"; import { Profile_Nostr_Event } from "../nostr.ts";
import { ProfileData } from "../features/profile.ts";
export const testEventBus = new EventBus<UI_Interaction_Event>(); export const testEventBus = new EventBus<UI_Interaction_Event>();
@ -65,7 +60,7 @@ export async function test_db_view() {
export const prepareProfileEvent = async ( export const prepareProfileEvent = async (
author: NostrAccountContext, author: NostrAccountContext,
profile: { name?: string; display_name?: string }, profile: ProfileData,
) => { ) => {
const profileEvent = await prepareNormalNostrEvent(author, { const profileEvent = await prepareNormalNostrEvent(author, {
kind: NostrKind.META_DATA, kind: NostrKind.META_DATA,

View File

@ -1,9 +1,8 @@
/** @jsx h */ /** @jsx h */
import { Component, h } from "preact"; import { Component, h } from "preact";
import { IconButtonClass } from "./tw.ts";
import { CloseIcon } from "../icons/close-icon.tsx";
import { ComponentChildren } from "preact"; import { ComponentChildren } from "preact";
import { Channel } from "@blowater/csp"; import { Channel } from "@blowater/csp";
import { XIcon } from "../icons/x-icon.tsx";
export type RightPanelChannel = Channel<(() => ComponentChildren) | undefined>; export type RightPanelChannel = Channel<(() => ComponentChildren) | undefined>;
@ -29,24 +28,19 @@ export class RightPanel extends Component<RightPanelProps, RightPanelState> {
render(_props: RightPanelProps, state: RightPanelState) { render(_props: RightPanelProps, state: RightPanelState) {
return ( return (
<div <div
class={`${state.children ? "" : "translate-x-full"} fixed top-0 right-0 border-l class={`${state.children ? "" : "translate-x-full"} fixed top-0 right-0
overflow-auto overflow-auto p-4
h-full bg-[#2F3136] h-full bg-neutral-600
z-20 transition duration-150 ease-in-out w-96 max-w-full z-20 transition duration-150 ease-in-out w-96 max-w-full
`} `}
> >
<button <button
class={`w-6 min-w-[1.5rem] h-6 ml-4 ${IconButtonClass} hover:bg-[#36393F] absolute right-2 top-3 z-10 border-2`} class={`h-8 w-8 hover:bg-neutral-500 absolute right-2 top-3 z-10 rounded-full flex justify-center items-center`}
onClick={() => { onClick={() => {
this.setState({ children: undefined }); this.setState({ children: undefined });
}} }}
> >
<CloseIcon <XIcon class="w-6 h-6 text-neutral-400" />
class={`w-4 h-4`}
style={{
stroke: "rgb(185, 187, 190)",
}}
/>
</button> </button>
{state.children ? state.children() : undefined} {state.children ? state.children() : undefined}
</div> </div>

View File

@ -1,11 +0,0 @@
{
"compilerOptions": {
"checkJs": false,
"lib": [
"DOM",
"ESNEXT"
],
"noImplicitAny": true
},
"lock": "./deno.lock"
}

View File

@ -1,111 +0,0 @@
{
"version": "3",
"remote": {
"https://deno.land/std@0.140.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74",
"https://deno.land/std@0.140.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49",
"https://deno.land/std@0.140.0/bytes/bytes_list.ts": "67eb118e0b7891d2f389dad4add35856f4ad5faab46318ff99653456c23b025d",
"https://deno.land/std@0.140.0/bytes/equals.ts": "fc16dff2090cced02497f16483de123dfa91e591029f985029193dfaa9d894c9",
"https://deno.land/std@0.140.0/bytes/mod.ts": "763f97d33051cc3f28af1a688dfe2830841192a9fea0cbaa55f927b49d49d0bf",
"https://deno.land/std@0.140.0/fmt/colors.ts": "30455035d6d728394781c10755351742dd731e3db6771b1843f9b9e490104d37",
"https://deno.land/std@0.140.0/fs/_util.ts": "0fb24eb4bfebc2c194fb1afdb42b9c3dda12e368f43e8f2321f84fc77d42cb0f",
"https://deno.land/std@0.140.0/fs/ensure_dir.ts": "9dc109c27df4098b9fc12d949612ae5c9c7169507660dcf9ad90631833209d9d",
"https://deno.land/std@0.140.0/io/buffer.ts": "bd0c4bf53db4b4be916ca5963e454bddfd3fcd45039041ea161dbf826817822b",
"https://deno.land/std@0.140.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3",
"https://deno.land/std@0.140.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09",
"https://deno.land/std@0.140.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b",
"https://deno.land/std@0.140.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633",
"https://deno.land/std@0.140.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee",
"https://deno.land/std@0.140.0/path/mod.ts": "d3e68d0abb393fb0bf94a6d07c46ec31dc755b544b13144dee931d8d5f06a52d",
"https://deno.land/std@0.140.0/path/posix.ts": "293cdaec3ecccec0a9cc2b534302dfe308adb6f10861fa183275d6695faace44",
"https://deno.land/std@0.140.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9",
"https://deno.land/std@0.140.0/path/win32.ts": "31811536855e19ba37a999cd8d1b62078235548d67902ece4aa6b814596dd757",
"https://deno.land/std@0.140.0/streams/conversion.ts": "712585bfa0172a97fb68dd46e784ae8ad59d11b88079d6a4ab098ff42e697d21",
"https://deno.land/std@0.176.0/encoding/hex.ts": "50f8c95b52eae24395d3dfcb5ec1ced37c5fe7610ef6fffdcc8b0fdc38e3b32f",
"https://deno.land/std@0.186.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462",
"https://deno.land/std@0.186.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3",
"https://deno.land/std@0.186.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0",
"https://deno.land/std@0.186.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b",
"https://deno.land/std@0.186.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0",
"https://deno.land/std@0.186.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000",
"https://deno.land/std@0.186.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1",
"https://deno.land/std@0.186.0/path/mod.ts": "ee161baec5ded6510ee1d1fb6a75a0f5e4b41f3f3301c92c716ecbdf7dae910d",
"https://deno.land/std@0.186.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d",
"https://deno.land/std@0.186.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1",
"https://deno.land/std@0.186.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba",
"https://deno.land/std@0.202.0/assert/assert.ts": "9a97dad6d98c238938e7540736b826440ad8c1c1e54430ca4c4e623e585607ee",
"https://deno.land/std@0.202.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56",
"https://deno.land/std@0.202.0/fs/_util.ts": "fbf57dcdc9f7bc8128d60301eece608246971a7836a3bb1e78da75314f08b978",
"https://deno.land/std@0.202.0/fs/walk.ts": "a16146724a6aaf9efdb92023a74e9805195c3469900744ce5de4113b07b29779",
"https://deno.land/std@0.202.0/path/_basename.ts": "057d420c9049821f983f784fd87fa73ac471901fb628920b67972b0f44319343",
"https://deno.land/std@0.202.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0",
"https://deno.land/std@0.202.0/path/_dirname.ts": "355e297236b2218600aee7a5301b937204c62e12da9db4b0b044993d9e658395",
"https://deno.land/std@0.202.0/path/_extname.ts": "eaaa5aae1acf1f03254d681bd6a8ce42a9cb5b7ff2213a9d4740e8ab31283664",
"https://deno.land/std@0.202.0/path/_format.ts": "4a99270d6810f082e614309164fad75d6f1a483b68eed97c830a506cc589f8b4",
"https://deno.land/std@0.202.0/path/_from_file_url.ts": "6eadfae2e6f63ad9ee46b26db4a1b16583055c0392acedfb50ed2fc694b6f581",
"https://deno.land/std@0.202.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b",
"https://deno.land/std@0.202.0/path/_is_absolute.ts": "05dac10b5e93c63198b92e3687baa2be178df5321c527dc555266c0f4f51558c",
"https://deno.land/std@0.202.0/path/_join.ts": "815f5e85b042285175b1492dd5781240ce126c23bd97bad6b8211fe7129c538e",
"https://deno.land/std@0.202.0/path/_normalize.ts": "a19ec8706b2707f9dd974662a5cd89fad438e62ab1857e08b314a8eb49a34d81",
"https://deno.land/std@0.202.0/path/_os.ts": "30b0c2875f360c9296dbe6b7f2d528f0f9c741cecad2e97f803f5219e91b40a2",
"https://deno.land/std@0.202.0/path/_parse.ts": "0f9b0ff43682dd9964eb1c4398610c4e165d8db9d3ac9d594220217adf480cfa",
"https://deno.land/std@0.202.0/path/_relative.ts": "27bdeffb5311a47d85be26d37ad1969979359f7636c5cd9fcf05dcd0d5099dc5",
"https://deno.land/std@0.202.0/path/_resolve.ts": "7a3616f1093735ed327e758313b79c3c04ea921808ca5f19ddf240cb68d0adf6",
"https://deno.land/std@0.202.0/path/_to_file_url.ts": "a141e4a525303e1a3a0c0571fd024552b5f3553a2af7d75d1ff3a503dcbb66d8",
"https://deno.land/std@0.202.0/path/_to_namespaced_path.ts": "0d5f4caa2ed98ef7a8786286df6af804b50e38859ae897b5b5b4c8c5930a75c8",
"https://deno.land/std@0.202.0/path/_util.ts": "4e191b1bac6b3bf0c31aab42e5ca2e01a86ab5a0d2e08b75acf8585047a86221",
"https://deno.land/std@0.202.0/path/basename.ts": "bdfa5a624c6a45564dc6758ef2077f2822978a6dbe77b0a3514f7d1f81362930",
"https://deno.land/std@0.202.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000",
"https://deno.land/std@0.202.0/path/dirname.ts": "b6533f4ee4174a526dec50c279534df5345836dfdc15318400b08c62a62a39dd",
"https://deno.land/std@0.202.0/path/extname.ts": "62c4b376300795342fe1e4746c0de518b4dc9c4b0b4617bfee62a2973a9555cf",
"https://deno.land/std@0.202.0/path/format.ts": "110270b238514dd68455a4c54956215a1aff7e37e22e4427b7771cefe1920aa5",
"https://deno.land/std@0.202.0/path/from_file_url.ts": "9f5cb58d58be14c775ec2e57fc70029ac8b17ed3bd7fe93e475b07280adde0ac",
"https://deno.land/std@0.202.0/path/glob.ts": "593e2c3573883225c25c5a21aaa8e9382a696b8e175ea20a3b6a1471ad17aaed",
"https://deno.land/std@0.202.0/path/is_absolute.ts": "0b92eb35a0a8780e9f16f16bb23655b67dace6a8e0d92d42039e518ee38103c1",
"https://deno.land/std@0.202.0/path/join.ts": "31c5419f23d91655b08ec7aec403f4e4cd1a63d39e28f6e42642ea207c2734f8",
"https://deno.land/std@0.202.0/path/mod.ts": "6e1efb0b13121463aedb53ea51dabf5639a3172ab58c89900bbb72b486872532",
"https://deno.land/std@0.202.0/path/normalize.ts": "6ea523e0040979dd7ae2f1be5bf2083941881a252554c0f32566a18b03021955",
"https://deno.land/std@0.202.0/path/parse.ts": "be8de342bb9e1924d78dc4d93c45215c152db7bf738ec32475560424b119b394",
"https://deno.land/std@0.202.0/path/posix.ts": "0a1c1952d132323a88736d03e92bd236f3ed5f9f079e5823fae07c8d978ee61b",
"https://deno.land/std@0.202.0/path/relative.ts": "8bedac226afd360afc45d451a6c29fabceaf32978526bcb38e0c852661f66c61",
"https://deno.land/std@0.202.0/path/resolve.ts": "133161e4949fc97f9ca67988d51376b0f5eef8968a6372325ab84d39d30b80dc",
"https://deno.land/std@0.202.0/path/separator.ts": "40a3e9a4ad10bef23bc2cd6c610291b6c502a06237c2c4cd034a15ca78dedc1f",
"https://deno.land/std@0.202.0/path/to_file_url.ts": "00e6322373dd51ad109956b775e4e72e5f9fa68ce2c6b04e4af2a6eed3825d31",
"https://deno.land/std@0.202.0/path/to_namespaced_path.ts": "1b1db3055c343ab389901adfbda34e82b7386bcd1c744d54f9c1496ee0fd0c3d",
"https://deno.land/std@0.202.0/path/win32.ts": "8b3f80ef7a462511d5e8020ff490edcaa0a0d118f1b1e9da50e2916bdd73f9dd",
"https://deno.land/x/deno_cache@0.5.2/auth_tokens.ts": "5d1d56474c54a9d152e44d43ea17c2e6a398dd1e9682c69811a313567c01ee1e",
"https://deno.land/x/deno_cache@0.5.2/cache.ts": "92ce8511e1e5c00fdf53a41619aa77d632ea8e0fc711324322e4d5ebf8133911",
"https://deno.land/x/deno_cache@0.5.2/deno_dir.ts": "1ea355b8ba11c630d076b222b197cfc937dd81e5a4a260938997da99e8ff93a0",
"https://deno.land/x/deno_cache@0.5.2/deps.ts": "26a75905652510b76e54b6d5ef3cf824d1062031e00782efcd768978419224e7",
"https://deno.land/x/deno_cache@0.5.2/dirs.ts": "009c6f54e0b610914d6ce9f72f6f6ccfffd2d47a79a19061e0a9eb4253836069",
"https://deno.land/x/deno_cache@0.5.2/disk_cache.ts": "66a1e604a8d564b6dd0500326cac33d08b561d331036bf7272def80f2f7952aa",
"https://deno.land/x/deno_cache@0.5.2/file_fetcher.ts": "89616c50b6df73fb04e73d0b7cd99e5f2ed7967386913d65b9e8baa4238501f7",
"https://deno.land/x/deno_cache@0.5.2/http_cache.ts": "407135eaf2802809ed373c230d57da7ef8dff923c4abf205410b9b99886491fd",
"https://deno.land/x/deno_cache@0.5.2/lib/deno_cache_dir.generated.js": "18b6526d0c50791a73dd0eb894e99de1ac05ee79dcbd53298ff5b5b6b0757fe6",
"https://deno.land/x/deno_cache@0.5.2/lib/snippets/deno_cache_dir-77bed54ace8005e0/fs.js": "cbe3a976ed63c72c7cb34ef845c27013033a3b11f9d8d3e2c4aa5dda2c0c7af6",
"https://deno.land/x/deno_cache@0.5.2/mod.ts": "0b4d071ad095128bdc2b1bc6e5d2095222dcbae08287261690ee9757e6300db6",
"https://deno.land/x/deno_cache@0.5.2/util.ts": "f3f5a0cfc60051f09162942fb0ee87a0e27b11a12aec4c22076e3006be4cc1e2",
"https://deno.land/x/dir@1.5.1/data_local_dir/mod.ts": "91eb1c4bfadfbeda30171007bac6d85aadacd43224a5ed721bbe56bc64e9eb66",
"https://deno.land/x/emit@0.31.0/_utils.ts": "98412edc7aa29e77d592b54fbad00bdec1b05d0c25eb772a5f8edc9813e08d88",
"https://deno.land/x/emit@0.31.0/emit.generated.js": "f2453b4a5243f2f5377e70e4577de0be57f99384c1a773bc5b786ad324739dac",
"https://deno.land/x/emit@0.31.0/mod.ts": "326c48e48f3f3c83c11b089aec803e6270bcd64493f250aeb56f46f6960a8458",
"https://deno.land/x/emit@0.32.0/_utils.ts": "98412edc7aa29e77d592b54fbad00bdec1b05d0c25eb772a5f8edc9813e08d88",
"https://deno.land/x/emit@0.32.0/emit.generated.js": "8c8e1fed94f6b742042897312ad223fff0f5d3c92317ff9970a5b7e8b2bd9441",
"https://deno.land/x/emit@0.32.0/mod.ts": "326c48e48f3f3c83c11b089aec803e6270bcd64493f250aeb56f46f6960a8458",
"https://deno.land/x/wasmbuild@0.14.1/cache.ts": "89eea5f3ce6035a1164b3e655c95f21300498920575ade23161421f5b01967f4",
"https://deno.land/x/wasmbuild@0.14.1/loader.ts": "d98d195a715f823151cbc8baa3f32127337628379a02d9eb2a3c5902dbccfc02",
"https://deno.land/x/wasmbuild@0.15.1/cache.ts": "9d01b5cb24e7f2a942bbd8d14b093751fa690a6cde8e21709ddc97667e6669ed",
"https://deno.land/x/wasmbuild@0.15.1/loader.ts": "8c2fc10e21678e42f84c5135d8ab6ab7dc92424c3f05d2354896a29ccfd02a63",
"https://esm.sh/dexie@3.2.4": "c47d1a2d892e605fde24fd9900602b11808018d5fb11a1c6ad91cec6bb0bf828",
"https://esm.sh/preact@10.11.3": "ad3c24796c4132c84b4b392f812228d53a0fd600fa64648f27aebd05ec09b24e",
"preact": "d9d10d95cd047fd2c26bb68e760a87d3747fafc64a1e54049095682c69c7491a",
"https://esm.sh/stable/preact@10.11.3/denonext/preact.mjs": "c828d9020ea26f07ba07b2f0a3ef97fd7ceb1c2a772c380ca05e2647ac8d3923",
"https://esm.sh/stable/preact@10.17.1/denonext/preact.mjs": "0f2f159289b4502eea839f4b57cef910ad03d63213ac5301e6767326b060d8f6",
"https://esm.sh/twind@0.16.16": "638f6fedc496ecb6bb6280be885145ab9bab0eee23478bace6018c7b28a4cd76",
"https://esm.sh/v135/dexie@3.2.4/denonext/dexie.mjs": "1ce1770b71be61358f3bbaf5b0667b395cf30052872e66d312178ebe0a72cca1",
"https://esm.sh/v135/style-vendorizer@2.2.3/denonext/style-vendorizer.mjs": "121455e7b04b631ef6463ce63cdcd29febd74d88c37713c774ceca8a1561c83d",
"https://esm.sh/v135/twind@0.16.16/denonext/twind.mjs": "857319af660b8bae96d20737a4f9a9b4ce909fcb47e0552abd559216824fe795",
"https://esm.sh/v135/zod@3.22.4/denonext/zod.mjs": "660128af5d1e921745c4d452472d103d9f2fc5afa508bbf233b83d35a272ad67",
"https://esm.sh/zod@3.22.4": "f7bfaf7e78bc8fa39e67e07c0dacd651925e889f5a4ef02b3ef6bab3925a8384",
"@blowater/csp": "4469313196bb1385ad38d13b72db0dbaf09a512c78d821144bc72b96c807417b"
}
}

View File

@ -0,0 +1,26 @@
/** @jsx h */
import { h } from "preact";
export function CopyIconV2(props: {
class?: string | h.JSX.SignalLike<string | undefined> | undefined;
style?:
| string
| h.JSX.CSSProperties
| h.JSX.SignalLike<string | h.JSX.CSSProperties>
| undefined;
}) {
return (
<svg
class={props.class}
style={props.style}
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M27 4H11C10.7348 4 10.4804 4.10536 10.2929 4.29289C10.1054 4.48043 10 4.73478 10 5V10H5C4.73478 10 4.48043 10.1054 4.29289 10.2929C4.10536 10.4804 4 10.7348 4 11V27C4 27.2652 4.10536 27.5196 4.29289 27.7071C4.48043 27.8946 4.73478 28 5 28H21C21.2652 28 21.5196 27.8946 21.7071 27.7071C21.8946 27.5196 22 27.2652 22 27V22H27C27.2652 22 27.5196 21.8946 27.7071 21.7071C27.8946 21.5196 28 21.2652 28 21V5C28 4.73478 27.8946 4.48043 27.7071 4.29289C27.5196 4.10536 27.2652 4 27 4ZM20 26H6V12H20V26ZM26 20H22V11C22 10.7348 21.8946 10.4804 21.7071 10.2929C21.5196 10.1054 21.2652 10 21 10H12V6H26V20Z"
fill="currentColor"
/>
</svg>
);
}

View File

@ -0,0 +1,26 @@
/** @jsx h */
import { h } from "preact";
export function GlobeIcon(props: {
class?: string | h.JSX.SignalLike<string | undefined> | undefined;
style?:
| string
| h.JSX.CSSProperties
| h.JSX.SignalLike<string | h.JSX.CSSProperties>
| undefined;
}) {
return (
<svg
class={props.class}
style={props.style}
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16 3C13.4288 3 10.9154 3.76244 8.77759 5.1909C6.63975 6.61935 4.9735 8.64968 3.98956 11.0251C3.00563 13.4006 2.74818 16.0144 3.24979 18.5362C3.7514 21.0579 4.98953 23.3743 6.80761 25.1924C8.62569 27.0105 10.9421 28.2486 13.4638 28.7502C15.9856 29.2518 18.5994 28.9944 20.9749 28.0104C23.3503 27.0265 25.3806 25.3603 26.8091 23.2224C28.2376 21.0846 29 18.5712 29 16C28.996 12.5534 27.6251 9.24911 25.188 6.812C22.7509 4.37488 19.4466 3.00397 16 3ZM27 16C27.0009 17.0145 26.8608 18.0241 26.5837 19H21.77C22.0767 17.0118 22.0767 14.9882 21.77 13H26.5837C26.8608 13.9759 27.0009 14.9855 27 16ZM12.75 21H19.25C18.6096 23.0982 17.498 25.0223 16 26.625C14.5026 25.0218 13.391 23.098 12.75 21ZM12.2625 19C11.9192 17.0147 11.9192 14.9853 12.2625 13H19.7475C20.0908 14.9853 20.0908 17.0147 19.7475 19H12.2625ZM5 16C4.99913 14.9855 5.13922 13.9759 5.41625 13H10.23C9.92333 14.9882 9.92333 17.0118 10.23 19H5.41625C5.13922 18.0241 4.99913 17.0145 5 16ZM19.25 11H12.75C13.3904 8.90176 14.502 6.97773 16 5.375C17.4974 6.97815 18.609 8.90204 19.25 11ZM25.7912 11H21.3387C20.7776 8.94113 19.8318 7.00709 18.5512 5.3C20.0984 5.67166 21.5469 6.37347 22.7974 7.35732C24.0479 8.34117 25.0709 9.58379 25.7962 11H25.7912ZM13.4487 5.3C12.1682 7.00709 11.2224 8.94113 10.6612 11H6.20375C6.92909 9.58379 7.95208 8.34117 9.20261 7.35732C10.4531 6.37347 11.9016 5.67166 13.4487 5.3ZM6.20375 21H10.6612C11.2224 23.0589 12.1682 24.9929 13.4487 26.7C11.9016 26.3283 10.4531 25.6265 9.20261 24.6427C7.95208 23.6588 6.92909 22.4162 6.20375 21ZM18.5512 26.7C19.8318 24.9929 20.7776 23.0589 21.3387 21H25.7962C25.0709 22.4162 24.0479 23.6588 22.7974 24.6427C21.5469 25.6265 20.0984 26.3283 18.5512 26.7Z"
fill="currentColor"
/>
</svg>
);
}

View File

@ -0,0 +1,26 @@
/** @jsx h */
import { h } from "preact";
export function XCircleIconV2(props: {
class?: string | h.JSX.SignalLike<string | undefined> | undefined;
style?:
| string
| h.JSX.CSSProperties
| h.JSX.SignalLike<string | h.JSX.CSSProperties>
| undefined;
}) {
return (
<svg
class={props.class}
style={props.style}
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M20.7075 12.7075L17.4138 16L20.7075 19.2925C20.8004 19.3854 20.8741 19.4957 20.9244 19.6171C20.9747 19.7385 21.0006 19.8686 21.0006 20C21.0006 20.1314 20.9747 20.2615 20.9244 20.3829C20.8741 20.5043 20.8004 20.6146 20.7075 20.7075C20.6146 20.8004 20.5043 20.8741 20.3829 20.9244C20.2615 20.9747 20.1314 21.0006 20 21.0006C19.8686 21.0006 19.7385 20.9747 19.6171 20.9244C19.4957 20.8741 19.3854 20.8004 19.2925 20.7075L16 17.4137L12.7075 20.7075C12.6146 20.8004 12.5043 20.8741 12.3829 20.9244C12.2615 20.9747 12.1314 21.0006 12 21.0006C11.8686 21.0006 11.7385 20.9747 11.6171 20.9244C11.4957 20.8741 11.3854 20.8004 11.2925 20.7075C11.1996 20.6146 11.1259 20.5043 11.0756 20.3829C11.0253 20.2615 10.9994 20.1314 10.9994 20C10.9994 19.8686 11.0253 19.7385 11.0756 19.6171C11.1259 19.4957 11.1996 19.3854 11.2925 19.2925L14.5863 16L11.2925 12.7075C11.1049 12.5199 10.9994 12.2654 10.9994 12C10.9994 11.7346 11.1049 11.4801 11.2925 11.2925C11.4801 11.1049 11.7346 10.9994 12 10.9994C12.2654 10.9994 12.5199 11.1049 12.7075 11.2925L16 14.5863L19.2925 11.2925C19.3854 11.1996 19.4957 11.1259 19.6171 11.0756C19.7385 11.0253 19.8686 10.9994 20 10.9994C20.1314 10.9994 20.2615 11.0253 20.3829 11.0756C20.5043 11.1259 20.6146 11.1996 20.7075 11.2925C20.8004 11.3854 20.8741 11.4957 20.9244 11.6171C20.9747 11.7385 21.0006 11.8686 21.0006 12C21.0006 12.1314 20.9747 12.2615 20.9244 12.3829C20.8741 12.5043 20.8004 12.6146 20.7075 12.7075ZM29 16C29 18.5712 28.2376 21.0846 26.8091 23.2224C25.3807 25.3603 23.3503 27.0265 20.9749 28.0104C18.5995 28.9944 15.9856 29.2518 13.4638 28.7502C10.9421 28.2486 8.6257 27.0105 6.80762 25.1924C4.98953 23.3743 3.75141 21.0579 3.2498 18.5362C2.74819 16.0144 3.00563 13.4006 3.98957 11.0251C4.97351 8.64968 6.63975 6.61935 8.77759 5.1909C10.9154 3.76244 13.4288 3 16 3C19.4467 3.00364 22.7512 4.37445 25.1884 6.81163C27.6256 9.24882 28.9964 12.5533 29 16ZM27 16C27 13.8244 26.3549 11.6977 25.1462 9.88873C23.9375 8.07979 22.2195 6.66989 20.2095 5.83733C18.1995 5.00476 15.9878 4.78692 13.854 5.21136C11.7202 5.6358 9.76021 6.68345 8.22183 8.22183C6.68345 9.7602 5.63581 11.7202 5.21137 13.854C4.78693 15.9878 5.00477 18.1995 5.83733 20.2095C6.66989 22.2195 8.07979 23.9375 9.88873 25.1462C11.6977 26.3549 13.8244 27 16 27C18.9164 26.9967 21.7123 25.8367 23.7745 23.7745C25.8367 21.7123 26.9967 18.9164 27 16Z"
fill="currentColor"
/>
</svg>
);
}

26
app/UI/icons/x-icon.tsx Normal file
View File

@ -0,0 +1,26 @@
/** @jsx h */
import { h } from "preact";
export function XIcon(props: {
class?: string | h.JSX.SignalLike<string | undefined> | undefined;
style?:
| string
| h.JSX.CSSProperties
| h.JSX.SignalLike<string | h.JSX.CSSProperties>
| undefined;
}) {
return (
<svg
class={props.class}
style={props.style}
viewBox="0 0 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M25.7075 24.2925C25.8004 24.3854 25.8741 24.4957 25.9244 24.6171C25.9747 24.7385 26.0006 24.8686 26.0006 25C26.0006 25.1314 25.9747 25.2615 25.9244 25.3829C25.8741 25.5043 25.8004 25.6146 25.7075 25.7075C25.6146 25.8004 25.5043 25.8741 25.3829 25.9244C25.2615 25.9747 25.1314 26.0006 25 26.0006C24.8686 26.0006 24.7385 25.9747 24.6171 25.9244C24.4957 25.8741 24.3854 25.8004 24.2925 25.7075L16 17.4138L7.70751 25.7075C7.51987 25.8951 7.26537 26.0006 7.00001 26.0006C6.73464 26.0006 6.48015 25.8951 6.29251 25.7075C6.10487 25.5199 5.99945 25.2654 5.99945 25C5.99945 24.7346 6.10487 24.4801 6.29251 24.2925L14.5863 16L6.29251 7.70751C6.10487 7.51987 5.99945 7.26537 5.99945 7.00001C5.99945 6.73464 6.10487 6.48015 6.29251 6.29251C6.48015 6.10487 6.73464 5.99945 7.00001 5.99945C7.26537 5.99945 7.51987 6.10487 7.70751 6.29251L16 14.5863L24.2925 6.29251C24.4801 6.10487 24.7346 5.99945 25 5.99945C25.2654 5.99945 25.5199 6.10487 25.7075 6.29251C25.8951 6.48015 26.0006 6.73464 26.0006 7.00001C26.0006 7.26537 25.8951 7.51987 25.7075 7.70751L17.4138 16L25.7075 24.2925Z"
fill="white"
/>
</svg>
);
}

View File

@ -0,0 +1,53 @@
/** @jsx h */
import { h, render } from "preact";
import { Channel } from "@blowater/csp";
import { CenterClass } from "./components/tw.ts";
import { prepareProfileEvent, testEventBus } from "./_setup.test.ts";
import { InMemoryAccountContext } from "@blowater/nostr-sdk";
import { RightPanel, RightPanelChannel } from "./components/right-panel.tsx";
import { UserDetail } from "./user-detail.tsx";
const ctx = InMemoryAccountContext.Generate();
const rightPanelChan: RightPanelChannel = new Channel();
const profileEvent = await prepareProfileEvent(ctx, {
name: "test_name",
display_name: "Orionna Lumis",
about:
"Celestial bodies move in a harmonious dance, bound by the tether of gravity. Their ballet paints stories in the sky.",
website: "https://github.com",
picture: "https://image.nostr.build/655007ae74f24ea1c611889f48b25cb485b83ab67408daddd98f95782f47e1b5.jpg",
});
function UserDetailTest() {
return (
<div class={`${CenterClass} w-screen h-screen text-white`}>
<button
class={`rounded bg-black px-4 py2`}
onClick={async () => {
await rightPanelChan.put(() => (
<UserDetail
targetUserProfile={profileEvent.profile}
pubkey={profileEvent.publicKey}
blocked={false}
emit={testEventBus.emit}
/>
));
}}
>
Show
</button>
<RightPanel inputChan={rightPanelChan} />
</div>
);
}
render(<UserDetailTest />, document.body);
for await (const event of testEventBus.onChange()) {
console.log(event);
if (event.type === "HideModal") {
await rightPanelChan.put(() => undefined);
}
}

View File

@ -5,15 +5,16 @@ import { PublicKey } from "@blowater/nostr-sdk";
import { ProfileData } from "../features/profile.ts"; import { ProfileData } from "../features/profile.ts";
import { emitFunc } from "../event-bus.ts"; import { emitFunc } from "../event-bus.ts";
import { DirectMessagePanelUpdate } from "./message-panel.tsx"; import { DirectMessagePanelUpdate } from "./message-panel.tsx";
import { HomeIcon } from "./icons/home-icon.tsx";
import { KeyIcon } from "./icons/key-icon.tsx";
import { UserIcon } from "./icons/user-icon.tsx";
import { CopyButton } from "./components/copy-button.tsx";
import { LinkColor } from "./style/colors.ts"; import { LinkColor } from "./style/colors.ts";
import { findUrlInString } from "./message.ts"; import { findUrlInString } from "./message.ts";
import { SelectConversation } from "./search_model.ts"; import { SelectConversation } from "./search_model.ts";
import { CloseRightPanel } from "./components/right-panel.tsx"; import { CloseRightPanel } from "./components/right-panel.tsx";
import { robohash } from "@blowater/nostr-sdk"; import { robohash } from "@blowater/nostr-sdk";
import { CopyIconV2 } from "./icons/copy-icon-v2.tsx";
import { GlobeIcon } from "./icons/globe-icon.tsx";
import { XCircleIconV2 } from "./icons/x-circle-icon-v2.tsx";
import { useState } from "preact/hooks";
import { sleep } from "@blowater/csp";
export type BlockUser = { export type BlockUser = {
type: "BlockUser"; type: "BlockUser";
@ -33,19 +34,70 @@ type UserDetailProps = {
}; };
export function UserDetail(props: UserDetailProps) { export function UserDetail(props: UserDetailProps) {
const [copyState, setCopyState] = useState<"copy" | "check">("copy");
const name = props.targetUserProfile.name || props.targetUserProfile.display_name || const name = props.targetUserProfile.name || props.targetUserProfile.display_name ||
props.pubkey.bech32(); props.pubkey.bech32();
const copyPublicKey = async () => {
if (copyState == "check") {
return;
}
navigator.clipboard.writeText(props.pubkey.bech32());
setCopyState("check");
await sleep(1500);
setCopyState("copy");
};
return ( return (
<div class={`px-2 py-3 text-[#7A818C]`}> <div class={`px-2 py-3 text-white flex flex-col justify-start gap-2`}>
<Avatar <Avatar
class={`w-64 h-64 m-auto`} class={`w-40 h-40 mb-2`}
picture={props.targetUserProfile.picture || robohash(props.pubkey.hex)} picture={props.targetUserProfile.picture || robohash(props.pubkey.hex)}
/> />
<div class="flex flex-col items-center"> <div
<h1 class={`text-lg font-semibold font-sans leading-7 truncate`}
class={`text-[#F3F4EA] truncate text-[1.4rem] my-4 max-w-full text-center` + >
` inline-block hover:text-[#60a5fa] hover:cursor-pointer`} {name}
onClick={(_) => { </div>
<div>
<button
class="rounded-lg bg-white/5 hover:bg-white/10 flex gap-1 justify-center items-center p-1"
onClick={copyPublicKey}
>
<CopyIconV2 class="w-4 h-4 text-white" />
<div class="text-sm font-semibold font-sans leading-5">
{copyState == "copy" ? "Public Key" : "Copied"}
</div>
</button>
</div>
{props.targetUserProfile.about
? (
<p
class={`flex-1 break-words overflow-hidden`}
>
{TextWithLinks({ text: props.targetUserProfile.about })}
</p>
)
: undefined}
{props.targetUserProfile.website
? (
<div class={`flex items-center overflow-hidden w-full gap-1`}>
<GlobeIcon class="w-4 h-4 text-neutral-400" />
<a
class={`flex-1 break-words overflow-hidden text-sm font-normal font-sans leading-5`}
href={props.targetUserProfile.website}
target="_blank"
rel="noopener noreferrer"
>
{props.targetUserProfile.website}
</a>
</div>
)
: undefined}
<div class="flex items-center gap-2">
<button
class="rounded-lg bg-blue-600 hover:bg-blue-700 px-2 py-1 text-sm font-semibold font-sans leading-5 hover:cursor-pointer"
onClick={() => {
props.emit({ props.emit({
type: "SelectConversation", type: "SelectConversation",
pubkey: props.pubkey, pubkey: props.pubkey,
@ -55,94 +107,27 @@ export function UserDetail(props: UserDetailProps) {
}); });
}} }}
> >
{name} Message
</h1> </button>
</div> <button
<div class={`flex items-start overflow-hidden w-full group`}> class="rounded-lg bg-neutral-100 hover:bg-white px-2 py-1 text-neutral-600 hover:text-neutral-800 text-sm font-semibold font-sans leading-5 hover:cursor-pointer flex items-center gap-1"
<KeyIcon onClick={() => {
class={`w-6 h-6 mr-2`} if (props.blocked) {
style={{ props.emit({
fill: "#7A818C", type: "UnblockUser",
pubkey: props.pubkey,
});
} else {
props.emit({
type: "BlockUser",
pubkey: props.pubkey,
});
}
}} }}
/>
<p
class={`flex-1 text-[#7A818C] group-hover:text-[#F3F4EA] break-words overflow-hidden`}
> >
{props.pubkey.bech32()} <XCircleIconV2 class="w-4 h-4" />
</p> {props.blocked ? "Unblock" : "Block"}
<CopyButton text={props.pubkey.bech32()} /> </button>
</div>
<div class={`flex items-start overflow-hidden w-full mt-1 group`}>
<KeyIcon
class={`w-6 h-6 mr-2`}
style={{
fill: "#7A818C",
}}
/>
<p
class={`flex-1 text-[#7A818C] group-hover:text-[#F3F4EA] break-words overflow-hidden`}
>
{props.pubkey.hex}
</p>
<CopyButton text={props.pubkey.hex} />
</div>
{props.targetUserProfile.about
? (
<div class={`flex items-start overflow-hidden w-full mt-4 group`}>
<UserIcon
class={`w-6 h-6 mr-2`}
style={{
stroke: "#7A818C",
strokeWidth: "1.5",
fill: "none",
}}
/>
<p
class={`flex-1 break-words overflow-hidden`}
>
{TextWithLinks({ text: props.targetUserProfile.about })}
</p>
</div>
)
: undefined}
{props.targetUserProfile.website
? (
<div class={`flex items-start overflow-hidden w-full mt-4 group`}>
<HomeIcon
class={`w-6 h-6 mr-2`}
style={{
stroke: "#7A818C",
strokeWidth: "1.5",
fill: "none",
}}
/>
<p
class={`flex-1 break-words overflow-hidden`}
>
{TextWithLinks({ text: props.targetUserProfile.website })}
</p>
</div>
)
: undefined}
<div class="py-1"></div>
<div
class="border inline-block select-none px-1 rounded-full
hover:text-[#D4D4D4] hover:cursor-pointer"
onClick={() => {
if (props.blocked) {
props.emit({
type: "UnblockUser",
pubkey: props.pubkey,
});
} else {
props.emit({
type: "BlockUser",
pubkey: props.pubkey,
});
}
}}
>
{props.blocked ? "Unblock" : "Block"}
</div> </div>
</div> </div>
); );

View File

@ -49,6 +49,7 @@
"@std/encoding": "jsr:@std/encoding@1.0.0", "@std/encoding": "jsr:@std/encoding@1.0.0",
"@std/fs": "jsr:@std/fs@0.229.3", "@std/fs": "jsr:@std/fs@0.229.3",
"@std/path": "jsr:@std/path@0.225.2", "@std/path": "jsr:@std/path@0.225.2",
"preact": "https://esm.sh/preact@10.22.1" "preact": "https://esm.sh/preact@10.22.1",
"preact/hooks": "https://esm.sh/preact@10.22.1/hooks"
} }
} }

View File

@ -14,7 +14,7 @@
"jsr:@std/encoding@0.213": "jsr:@std/encoding@0.213.1", "jsr:@std/encoding@0.213": "jsr:@std/encoding@0.213.1",
"jsr:@std/encoding@0.224.3": "jsr:@std/encoding@0.224.3", "jsr:@std/encoding@0.224.3": "jsr:@std/encoding@0.224.3",
"jsr:@std/fs@0.229.3": "jsr:@std/fs@0.229.3", "jsr:@std/fs@0.229.3": "jsr:@std/fs@0.229.3",
"jsr:@std/internal@^1.0.0": "jsr:@std/internal@1.0.1", "jsr:@std/internal@^1.0.0": "jsr:@std/internal@1.0.0",
"jsr:@std/jsonc@0.213": "jsr:@std/jsonc@0.213.1", "jsr:@std/jsonc@0.213": "jsr:@std/jsonc@0.213.1",
"jsr:@std/path@0.213": "jsr:@std/path@0.213.1", "jsr:@std/path@0.213": "jsr:@std/path@0.213.1",
"jsr:@std/path@0.225.2": "jsr:@std/path@0.225.2", "jsr:@std/path@0.225.2": "jsr:@std/path@0.225.2",
@ -86,9 +86,6 @@
"@std/internal@1.0.0": { "@std/internal@1.0.0": {
"integrity": "ac6a6dfebf838582c4b4f61a6907374e27e05bedb6ce276e0f1608fe84e7cd9a" "integrity": "ac6a6dfebf838582c4b4f61a6907374e27e05bedb6ce276e0f1608fe84e7cd9a"
}, },
"@std/internal@1.0.1": {
"integrity": "6f8c7544d06a11dd256c8d6ba54b11ed870aac6c5aeafff499892662c57673e6"
},
"@std/jsonc@0.213.1": { "@std/jsonc@0.213.1": {
"integrity": "5578f21aa583b7eb7317eed077ffcde47b294f1056bdbb9aacec407758637bfe", "integrity": "5578f21aa583b7eb7317eed077ffcde47b294f1056bdbb9aacec407758637bfe",
"dependencies": [ "dependencies": [
@ -400,6 +397,8 @@
"https://deno.land/std@0.202.0/assert/fail.ts": "c36353d7ae6e1f7933d45f8ea51e358c8c4b67d7e7502028598fe1fea062e278", "https://deno.land/std@0.202.0/assert/fail.ts": "c36353d7ae6e1f7933d45f8ea51e358c8c4b67d7e7502028598fe1fea062e278",
"https://deno.land/std@0.202.0/fmt/colors.ts": "c51c4642678eb690dcf5ffee5918b675bf01a33fba82acf303701ae1a4f8c8d9", "https://deno.land/std@0.202.0/fmt/colors.ts": "c51c4642678eb690dcf5ffee5918b675bf01a33fba82acf303701ae1a4f8c8d9",
"https://esm.sh/preact@10.22.1": "c82def411ae2b4030ca15b6b19743ce83b8edb749c1ebc6014faa76b84acface", "https://esm.sh/preact@10.22.1": "c82def411ae2b4030ca15b6b19743ce83b8edb749c1ebc6014faa76b84acface",
"https://esm.sh/preact@10.22.1/hooks": "391c9f21c7d5f1a5725d96ba54bc903c0855c3c3727b54d6691fa9f8fa1ba488",
"https://esm.sh/stable/preact@10.22.1/denonext/hooks.js": "5c79b37c4b13be590576ba53bd4093beb6e95c10ee475cddf5af5051a6e040fa",
"https://esm.sh/stable/preact@10.22.1/denonext/preact.mjs": "516caa8df1109e0b82becdb053e7d956802ee2f3e3fa7f6925291e4d4a527706", "https://esm.sh/stable/preact@10.22.1/denonext/preact.mjs": "516caa8df1109e0b82becdb053e7d956802ee2f3e3fa7f6925291e4d4a527706",
"https://esm.sh/v135/dexie@3.2.4/denonext/dist/dexie.js": "20d7fea3aad3a1b5d91b7d43590df26f3132c429b731d2dd77697d2a60f67a79", "https://esm.sh/v135/dexie@3.2.4/denonext/dist/dexie.js": "20d7fea3aad3a1b5d91b7d43590df26f3132c429b731d2dd77697d2a60f67a79",
"https://esm.sh/v135/dexie@3.2.4/dist/dexie.js": "09d2f84b77cc12ac170004634c8560bc7d40a43920ff99166a269a034c48704b" "https://esm.sh/v135/dexie@3.2.4/dist/dexie.js": "09d2f84b77cc12ac170004634c8560bc7d40a43920ff99166a269a034c48704b"