mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-18 03:03:31 +00:00
added emoji picker
This commit is contained in:
parent
dbe9985739
commit
0c659b0902
@ -12,6 +12,8 @@
|
||||
"**/*": "prettier --write --ignore-unknown"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emoji-mart/data": "^1.1.2",
|
||||
"@emoji-mart/react": "^1.1.1",
|
||||
"@radix-ui/react-collapsible": "^1.0.2",
|
||||
"@radix-ui/react-dialog": "^1.0.3",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.4",
|
||||
@ -28,6 +30,7 @@
|
||||
"boring-avatars": "^1.7.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"destr": "^1.2.2",
|
||||
"emoji-mart": "^5.5.2",
|
||||
"framer-motion": "^9.1.7",
|
||||
"jotai": "^2.0.3",
|
||||
"jotai-cache": "^0.3.0",
|
||||
|
@ -1,6 +1,8 @@
|
||||
lockfileVersion: 5.4
|
||||
|
||||
specifiers:
|
||||
'@emoji-mart/data': ^1.1.2
|
||||
'@emoji-mart/react': ^1.1.1
|
||||
'@radix-ui/react-collapsible': ^1.0.2
|
||||
'@radix-ui/react-dialog': ^1.0.3
|
||||
'@radix-ui/react-dropdown-menu': ^2.0.4
|
||||
@ -27,6 +29,7 @@ specifiers:
|
||||
csstype: ^3.1.1
|
||||
dayjs: ^1.11.7
|
||||
destr: ^1.2.2
|
||||
emoji-mart: ^5.5.2
|
||||
eslint: ^8.36.0
|
||||
eslint-config-next: ^13.2.4
|
||||
eslint-config-prettier: ^8.8.0
|
||||
@ -58,6 +61,8 @@ specifiers:
|
||||
ws: ^8.13.0
|
||||
|
||||
dependencies:
|
||||
'@emoji-mart/data': 1.1.2
|
||||
'@emoji-mart/react': 1.1.1_kyrnz3vmphzqyjjk2ivrm6bcsu
|
||||
'@radix-ui/react-collapsible': 1.0.2_biqbaboplfbrettd7655fr4n2y
|
||||
'@radix-ui/react-dialog': 1.0.3_aen5vu2fkbnw3ssyd5drxdxkh4
|
||||
'@radix-ui/react-dropdown-menu': 2.0.4_aen5vu2fkbnw3ssyd5drxdxkh4
|
||||
@ -74,6 +79,7 @@ dependencies:
|
||||
boring-avatars: 1.7.0
|
||||
dayjs: 1.11.7
|
||||
destr: 1.2.2
|
||||
emoji-mart: 5.5.2
|
||||
framer-motion: 9.1.7_biqbaboplfbrettd7655fr4n2y
|
||||
jotai: 2.0.3_react@18.2.0
|
||||
jotai-cache: 0.3.0_jotai@2.0.3
|
||||
@ -375,6 +381,22 @@ packages:
|
||||
'@babel/helper-validator-identifier': 7.19.1
|
||||
to-fast-properties: 2.0.0
|
||||
|
||||
/@emoji-mart/data/1.1.2:
|
||||
resolution:
|
||||
{ integrity: sha512-1HP8BxD2azjqWJvxIaWAMyTySeZY0Osr83ukYjltPVkNXeJvTz7yDrPLBtnrD5uqJ3tg4CcLuuBW09wahqL/fg== }
|
||||
dev: false
|
||||
|
||||
/@emoji-mart/react/1.1.1_kyrnz3vmphzqyjjk2ivrm6bcsu:
|
||||
resolution:
|
||||
{ integrity: sha512-NMlFNeWgv1//uPsvLxvGQoIerPuVdXwK/EUek8OOkJ6wVOWPUizRBJU0hDqWZCOROVpfBgCemaC3m6jDOXi03g== }
|
||||
peerDependencies:
|
||||
emoji-mart: ^5.2
|
||||
react: ^16.8 || ^17 || ^18
|
||||
dependencies:
|
||||
emoji-mart: 5.5.2
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@emotion/is-prop-valid/0.8.8:
|
||||
resolution:
|
||||
{ integrity: sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== }
|
||||
@ -2511,6 +2533,11 @@ packages:
|
||||
resolution:
|
||||
{ integrity: sha512-zx8hqumOqltKsv/MF50yvdAlPF9S/4PXbyfzJS6ZGhbddGkRegdwImmfSVqCkEziYzrIGZ/TlrzBND4FysfkDg== }
|
||||
|
||||
/emoji-mart/5.5.2:
|
||||
resolution:
|
||||
{ integrity: sha512-Sqc/nso4cjxhOwWJsp9xkVm8OF5c+mJLZJFoFfzRuKO+yWiN7K8c96xmtughYb0d/fZ8UC6cLIQ/p4BR6Pv3/A== }
|
||||
dev: false
|
||||
|
||||
/emoji-regex/8.0.0:
|
||||
resolution:
|
||||
{ integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== }
|
||||
|
18
src/assets/icons/emoji.tsx
Normal file
18
src/assets/icons/emoji.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
export default function EmojiIcon({ className }: { className: string }) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className={className}
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M15.182 15.182a4.5 4.5 0 01-6.364 0M21 12a9 9 0 11-18 0 9 9 0 0118 0zM9.75 9.75c0 .414-.168.75-.375.75S9 10.164 9 9.75 9.168 9 9.375 9s.375.336.375.75zm-.375 0h.008v.015h-.008V9.75zm5.625 0c0 .414-.168.75-.375.75s-.375-.336-.375-.75.168-.75.375-.75.375.336.375.75zm-.375 0h.008v.015h-.008V9.75z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
18
src/assets/icons/image.tsx
Normal file
18
src/assets/icons/image.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
export default function ImageIcon({ className }: { className: string }) {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className={className}
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
@ -1,14 +1,19 @@
|
||||
import EmojiPicker from '@components/form/emojiPicker';
|
||||
import { RelayContext } from '@components/relaysProvider';
|
||||
|
||||
import { activeAccountAtom } from '@stores/account';
|
||||
import { noteContentAtom } from '@stores/note';
|
||||
import { relaysAtom } from '@stores/relays';
|
||||
|
||||
import { dateToUnix } from '@utils/getDate';
|
||||
|
||||
import ImageIcon from '@assets/icons/image';
|
||||
|
||||
import * as Dialog from '@radix-ui/react-dialog';
|
||||
import { SizeIcon } from '@radix-ui/react-icons';
|
||||
import * as commands from '@uiw/react-md-editor/lib/commands';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import { useResetAtom } from 'jotai/utils';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { getEventHash, signEvent } from 'nostr-tools';
|
||||
import { useContext, useState } from 'react';
|
||||
@ -17,14 +22,15 @@ const MDEditor = dynamic(() => import('@uiw/react-md-editor').then((mod) => mod.
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
export default function FormBasic() {
|
||||
export default function FormBase() {
|
||||
const pool: any = useContext(RelayContext);
|
||||
|
||||
const relays = useAtomValue(relaysAtom);
|
||||
const [activeAccount] = useAtom(activeAccountAtom);
|
||||
const [value, setValue] = useAtom(noteContentAtom);
|
||||
const resetValue = useResetAtom(noteContentAtom);
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const [value, setValue] = useState('');
|
||||
|
||||
const pubkey = activeAccount.id;
|
||||
const privkey = activeAccount.privkey;
|
||||
@ -41,7 +47,7 @@ export default function FormBasic() {
|
||||
event.sig = signEvent(event, privkey);
|
||||
|
||||
pool.publish(event, relays);
|
||||
setValue('');
|
||||
resetValue;
|
||||
};
|
||||
|
||||
const postButton = {
|
||||
@ -49,9 +55,9 @@ export default function FormBasic() {
|
||||
keyCommand: 'post',
|
||||
buttonProps: { className: 'cta-btn', 'aria-label': 'Post a message' },
|
||||
icon: (
|
||||
<button className="inline-flex h-8 w-16 items-center justify-center rounded-md bg-fuchsia-500 px-4 text-sm font-medium shadow-md shadow-fuchsia-900/50 hover:bg-fuchsia-600 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50">
|
||||
<div className="inline-flex h-8 w-16 items-center justify-center rounded-md bg-fuchsia-500 px-4 text-sm font-medium shadow-md shadow-fuchsia-900/50 hover:bg-fuchsia-600 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50">
|
||||
<span className="text-white drop-shadow">Send</span>
|
||||
</button>
|
||||
</div>
|
||||
),
|
||||
execute: (state: { text: any }) => {
|
||||
if (state.text > 0) {
|
||||
@ -82,37 +88,9 @@ export default function FormBasic() {
|
||||
</span>
|
||||
</Dialog.Trigger>
|
||||
<div className="flex items-center gap-2 pl-2">
|
||||
<EmojiPicker />
|
||||
<span className="inline-flex h-6 w-6 cursor-pointer items-center justify-center rounded-md hover:bg-zinc-700">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="h-4 w-4 text-zinc-400"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M15.182 15.182a4.5 4.5 0 01-6.364 0M21 12a9 9 0 11-18 0 9 9 0 0118 0zM9.75 9.75c0 .414-.168.75-.375.75S9 10.164 9 9.75 9.168 9 9.375 9s.375.336.375.75zm-.375 0h.008v.015h-.008V9.75zm5.625 0c0 .414-.168.75-.375.75s-.375-.336-.375-.75.168-.75.375-.75.375.336.375.75zm-.375 0h.008v.015h-.008V9.75z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span className="inline-flex h-6 w-6 cursor-pointer items-center justify-center rounded-md hover:bg-zinc-700">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={1.5}
|
||||
stroke="currentColor"
|
||||
className="h-4 w-4 text-zinc-400"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z"
|
||||
/>
|
||||
</svg>
|
||||
<ImageIcon className="h-4 w-4 text-zinc-400" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
@ -2,22 +2,25 @@ import { ImageWithFallback } from '@components/imageWithFallback';
|
||||
import { RelayContext } from '@components/relaysProvider';
|
||||
|
||||
import { activeAccountAtom } from '@stores/account';
|
||||
import { noteContentAtom } from '@stores/note';
|
||||
import { relaysAtom } from '@stores/relays';
|
||||
|
||||
import { dateToUnix } from '@utils/getDate';
|
||||
|
||||
import destr from 'destr';
|
||||
import { useAtom, useAtomValue } from 'jotai';
|
||||
import { useResetAtom } from 'jotai/utils';
|
||||
import { getEventHash, signEvent } from 'nostr-tools';
|
||||
import { useContext, useState } from 'react';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export default function FormComment({ eventID }: { eventID: any }) {
|
||||
export default function FormComment({ eventID }: { eventID: string }) {
|
||||
const pool: any = useContext(RelayContext);
|
||||
|
||||
const relays = useAtomValue(relaysAtom);
|
||||
const [activeAccount] = useAtom(activeAccountAtom);
|
||||
const [value, setValue] = useAtom(noteContentAtom);
|
||||
const resetValue = useResetAtom(noteContentAtom);
|
||||
|
||||
const [value, setValue] = useState('');
|
||||
const profile = destr(activeAccount.metadata);
|
||||
|
||||
const submitEvent = () => {
|
||||
@ -32,6 +35,7 @@ export default function FormComment({ eventID }: { eventID: any }) {
|
||||
event.sig = signEvent(event, activeAccount.privkey);
|
||||
|
||||
pool.publish(event, relays);
|
||||
resetValue;
|
||||
};
|
||||
|
||||
return (
|
37
src/components/form/emojiPicker.tsx
Normal file
37
src/components/form/emojiPicker.tsx
Normal file
@ -0,0 +1,37 @@
|
||||
import { noteContentAtom } from '@stores/note';
|
||||
|
||||
import EmojiIcon from '@assets/icons/emoji';
|
||||
|
||||
import data from '@emoji-mart/data';
|
||||
import Picker from '@emoji-mart/react';
|
||||
import * as Popover from '@radix-ui/react-popover';
|
||||
import { useAtom } from 'jotai';
|
||||
|
||||
export default function EmojiPicker() {
|
||||
const [value, setValue] = useAtom(noteContentAtom);
|
||||
|
||||
return (
|
||||
<Popover.Root>
|
||||
<Popover.Trigger asChild>
|
||||
<button className="inline-flex h-6 w-6 cursor-pointer items-center justify-center rounded-md hover:bg-zinc-700">
|
||||
<EmojiIcon className="h-4 w-4 text-zinc-400" />
|
||||
</button>
|
||||
</Popover.Trigger>
|
||||
<Popover.Portal>
|
||||
<Popover.Content
|
||||
className="rounded-md will-change-[transform,opacity] data-[state=open]:data-[side=top]:animate-slideDownAndFade data-[state=open]:data-[side=right]:animate-slideLeftAndFade data-[state=open]:data-[side=bottom]:animate-slideUpAndFade data-[state=open]:data-[side=left]:animate-slideRightAndFade"
|
||||
sideOffset={5}
|
||||
>
|
||||
<Picker
|
||||
data={data}
|
||||
emojiSize={16}
|
||||
navPosition={'none'}
|
||||
skinTonePosition={'none'}
|
||||
onEmojiSelect={(res) => setValue(value + ' ' + res.native)}
|
||||
/>
|
||||
<Popover.Arrow className="fill-[#141516]" />
|
||||
</Popover.Content>
|
||||
</Popover.Portal>
|
||||
</Popover.Root>
|
||||
);
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import BaseLayout from '@layouts/base';
|
||||
import WithSidebarLayout from '@layouts/withSidebar';
|
||||
|
||||
import FormComment from '@components/form/comment';
|
||||
import { NoteExtend } from '@components/note/extend';
|
||||
import FormComment from '@components/note/form/comment';
|
||||
import { RelayContext } from '@components/relaysProvider';
|
||||
|
||||
import { relaysAtom } from '@stores/relays';
|
||||
|
@ -1,8 +1,8 @@
|
||||
import BaseLayout from '@layouts/base';
|
||||
import WithSidebarLayout from '@layouts/withSidebar';
|
||||
|
||||
import FormBasic from '@components/form/base';
|
||||
import { NoteBase } from '@components/note/base';
|
||||
import FormBasic from '@components/note/form/basic';
|
||||
import { Placeholder } from '@components/note/placeholder';
|
||||
|
||||
import { notesAtom } from '@stores/note';
|
||||
|
@ -3,7 +3,10 @@ import { getAllNotes } from '@utils/storage';
|
||||
|
||||
import { atom } from 'jotai';
|
||||
import { atomsWithQuery } from 'jotai-tanstack-query';
|
||||
import { atomWithReset } from 'jotai/utils';
|
||||
|
||||
// note content
|
||||
export const noteContentAtom = atomWithReset('');
|
||||
// notify user that connector has receive newer note
|
||||
export const hasNewerNoteAtom = atom(false);
|
||||
// query notes from database
|
||||
|
Loading…
Reference in New Issue
Block a user