From ded15540a202b71f824f92b31767c6249a4f192b Mon Sep 17 00:00:00 2001 From: Bojan Mojsilovic Date: Tue, 2 Apr 2024 15:45:39 +0200 Subject: [PATCH] Refactor notes --- src/components/Note/Note.module.scss | 165 +++++++++- src/components/Note/Note.tsx | 295 +++++++++++++++--- src/components/Note/NoteContextMenu.tsx | 1 + src/components/Note/NoteContextTrigger.tsx | 28 ++ .../Note/NoteFooter/NoteFooter.module.scss | 4 +- src/components/Note/NoteFooter/NoteFooter.tsx | 292 ++++++----------- .../NoteFooter/NoteFooterActionButton.tsx | 50 +++ .../NotificationItem.module.scss | 2 +- .../Notifications/NotificationItem.tsx | 4 +- .../Notifications/NotificationItemOld.tsx | 4 +- src/lib/feed.ts | 9 +- src/pages/Notifications.module.scss | 50 +-- src/pages/Thread.tsx | 3 +- 13 files changed, 631 insertions(+), 276 deletions(-) create mode 100644 src/components/Note/NoteContextTrigger.tsx create mode 100644 src/components/Note/NoteFooter/NoteFooterActionButton.tsx diff --git a/src/components/Note/Note.module.scss b/src/components/Note/Note.module.scss index 5092678..e2979e3 100644 --- a/src/components/Note/Note.module.scss +++ b/src/components/Note/Note.module.scss @@ -234,13 +234,158 @@ font-weight: bold; } - .verificationFailed { display: inline-block; width: 4px; height: 4px; } +.notePrimary { + position: relative; + background-color: var(--background-card); + display: flex; + flex-direction: column; + padding: 12px; + padding-top: 0; + border-radius: 0; + border: none; + + .content { + grid-area: content; + display: flex; + flex-direction: column; + margin-left: 2px; + margin-top: 2px; + cursor: text; + + + .message { + position: relative; + grid-area: message; + color: var(--text-primary); + word-break: break-word; + font-size: 18px; + font-weight: 400; + line-height: 24px; + width: 100%; + margin-bottom: 12px; + + a:hover { + text-decoration: underline; + } + + .messageFade { + position: absolute; + z-index: 1; + top: 610px; + left: 0; + pointer-events: none; + background-image: var(--fade-note-vertical); + width: 100%; + height: 40px; + } + + } + } +} + +.noteNotificationLink { + text-decoration: none; + color: unset; + margin: 0px; + padding: 0px; + // background: var(--brand-gradient-vertical); + background-color: var(--background-card); + border-radius: 6px; + display: block; + transition: 0.2s padding; + margin-top: 6px; + + .noteNotifications { + background-color: var(--background-site); + display: grid; + grid-template-columns: 1fr; + grid-template-rows: 1fr; + grid-template-areas: "content"; + padding: 0px; + border-radius: 4px; + transition: 0.2s border-radius ease-out; + + .content { + grid-area: content; + display: flex; + flex-direction: column; + + + .message { + grid-area: message; + color: var(--text-primary); + word-break: break-word; + font-size: 16px; + line-height: 24px; + width: 100%; + + a:hover { + text-decoration: underline; + } + } + + .footer { + margin-top: 12px; + } + } + } + + // &:hover { + // padding-left: 4px; + // transition: 0.2s padding; + // border-radius: 4px; + // >div { + // border-radius: 0px 4px 4px 0px; + // transition: 0.2s border-radius ease-out; + // } + // } +} + +.context { + background: none; + display: flex; + justify-content: flex-end; + align-items: center; + + .contextButton { + width: 42px; + height: 32px; + padding: 0; + margin: 0; + background: none; + border: none; + outline: none; + display: flex; + justify-content: center; + align-items: center; + + &:focus { + outline: none; + box-shadow: none; + } + + .contextIcon { + width: 16px; + height: 14px; + background-color: var(--text-secondary-2); + -webkit-mask: url(../../assets/icons/context.svg) no-repeat 0 / 100%; + mask: url(../../assets/icons/context.svg) no-repeat 0 / 100%; + } + + &:hover { + .contextIcon { + background-color: var(--text-primary); + } + } + } +} + @media only screen and (max-width: 720px) { .note { width: 100dvw; @@ -258,6 +403,24 @@ width: 100%; } + .notePrimary { + width: 100vw; + margin-left: 0px; + margin-right: 0px; + padding-right: 12px; + .content { + margin-left: 0px; + } + } + + .noteNotificationLink { + .noteNotifications { + grid-template-columns: 1fr; + margin-left: 0px; + margin-right: 0px; + padding-right: 0px; + } + } } .upRightFloater { diff --git a/src/components/Note/Note.tsx b/src/components/Note/Note.tsx index 6046a99..96bb6bf 100644 --- a/src/components/Note/Note.tsx +++ b/src/components/Note/Note.tsx @@ -1,6 +1,6 @@ import { A } from '@solidjs/router'; -import { Component, Show } from 'solid-js'; -import { PrimalNote } from '../../types/primal'; +import { batch, Component, Match, Show, Switch } from 'solid-js'; +import { PrimalNote, ZapOption } from '../../types/primal'; import ParsedNote from '../ParsedNote/ParsedNote'; import NoteFooter from './NoteFooter/NoteFooter'; @@ -12,71 +12,268 @@ import Avatar from '../Avatar/Avatar'; import NoteAuthorInfo from './NoteAuthorInfo'; import NoteRepostHeader from './NoteRepostHeader'; import NoteReplyToHeader from './NoteReplyToHeader'; -import BookmarkNote from '../BookmarkNote/BookmarkNote'; +import NoteHeader from './NoteHeader/NoteHeader'; +import { createStore } from 'solid-js/store'; +import { CustomZapInfo, useAppContext } from '../../contexts/AppContext'; +import NoteContextTrigger from './NoteContextTrigger'; -const Note: Component<{ note: PrimalNote, id?: string, parent?: boolean, shorten?: boolean }> = (props) => { +export type NoteFooterState = { + likes: number, + liked: boolean, + reposts: number, + reposted: boolean, + replies: number, + replied: boolean, + zapCount: number, + satsZapped: number, + zappedAmount: number, + zapped: boolean, + zappedNow: boolean, + isZapping: boolean, + showZapAnim: boolean, + hideZapIcon: boolean, + isRepostMenuVisible: boolean, +}; + +const Note: Component<{ + note: PrimalNote, + id?: string, + parent?: boolean, + shorten?: boolean, + noteType?: 'feed' | 'primary' | 'notification' +}> = (props) => { const threadContext = useThreadContext(); + const app = useAppContext(); const intl = useIntl(); + const noteType = () => props.noteType || 'feed'; + const repost = () => props.note.repost; const navToThread = (note: PrimalNote) => { threadContext?.actions.setPrimaryNote(note); }; - return ( - navToThread(props.note)} - data-event={props.note.post.id} - data-event-bech32={props.note.post.noteId} - draggable={false} - > -
- - - -
-
-
- - - - -
-
-
+ const [footerState, updateFooterState] = createStore({ + likes: props.note.post.likes, + liked: props.note.post.noteActions.liked, + reposts: props.note.post.reposts, + reposted: props.note.post.noteActions.reposted, + replies: props.note.post.replies, + replied: props.note.post.noteActions.replied, + zapCount: props.note.post.zaps, + satsZapped: props.note.post.satszapped, + zapped: props.note.post.noteActions.zapped, + zappedAmount: 0, + zappedNow: false, + isZapping: false, + showZapAnim: false, + hideZapIcon: false, + isRepostMenuVisible: false, + }); -
- + let noteContextMenu: HTMLDivElement | undefined; + + const onConfirmZap = (zapOption: ZapOption) => { + app?.actions.closeCustomZapModal(); + batch(() => { + updateFooterState('zappedAmount', () => zapOption.amount || 0); + updateFooterState('zappedNow', () => true); + updateFooterState('zapped', () => true); + updateFooterState('showZapAnim', () => true) + }); + }; + + const onSuccessZap = (zapOption: ZapOption) => { + app?.actions.closeCustomZapModal(); + batch(() => { + updateFooterState('isZapping', () => false); + updateFooterState('zappedNow', () => false); + updateFooterState('showZapAnim', () => false); + updateFooterState('hideZapIcon', () => false); + updateFooterState('zapped', () => true); + }); + }; + + const onFailZap = (zapOption: ZapOption) => { + app?.actions.closeCustomZapModal(); + batch(() => { + updateFooterState('zappedAmount', () => -(zapOption.amount || 0)); + updateFooterState('isZapping', () => false); + updateFooterState('zappedNow', () => true); + updateFooterState('showZapAnim', () => false); + updateFooterState('hideZapIcon', () => false); + updateFooterState('zapped', () => props.note.post.noteActions.zapped); + }); + }; + + const onCancelZap = (zapOption: ZapOption) => { + app?.actions.closeCustomZapModal(); + batch(() => { + updateFooterState('zappedAmount', () => -(zapOption.amount || 0)); + updateFooterState('isZapping', () => false); + updateFooterState('zappedNow', () => true); + updateFooterState('showZapAnim', () => false); + updateFooterState('hideZapIcon', () => false); + updateFooterState('zapped', () => props.note.post.noteActions.zapped); + }); + }; + + const customZapInfo: CustomZapInfo = { + note: props.note, + onConfirm: onConfirmZap, + onSuccess: onSuccessZap, + onFail: onFailZap, + onCancel: onCancelZap, + }; + + const onContextMenuTrigger = () => { + app?.actions.openContextMenu( + props.note, + noteContextMenu?.getBoundingClientRect(), + () => { + app?.actions.openCustomZapModal(customZapInfo); + }, + () => { + app?.actions.openReactionModal(props.note.post.id, { + likes: footerState.likes, + zaps: footerState.zapCount, + reposts: footerState.reposts, + quotes: 0, + }); + } + ); + } + + return ( + + + navToThread(props.note)} + data-event={props.note.post.id} + data-event-bech32={props.note.post.noteId} + > +
+
+
+ +
+ +
+ +
+
+
+
+
+ + +
+
+ +
- -
- - - -
-
- +
+ +
+ +
+ + +
-
- - ) + + + + + navToThread(props.note)} + data-event={props.note.post.id} + data-event-bech32={props.note.post.noteId} + draggable={false} + > +
+ + + +
+
+
+ + + + +
+
+
+ +
+ + +
+ +
+ + + +
+ +
+ + +
+
+ +
+ + ); } export default hookForDev(Note); diff --git a/src/components/Note/NoteContextMenu.tsx b/src/components/Note/NoteContextMenu.tsx index e517a58..b712d33 100644 --- a/src/components/Note/NoteContextMenu.tsx +++ b/src/components/Note/NoteContextMenu.tsx @@ -51,6 +51,7 @@ const NoteContextMenu: Component<{ if (!props.open) { context.setAttribute('style',`top: -1024px; left: -1034px;`); + return; } const docRect = document.documentElement.getBoundingClientRect(); diff --git a/src/components/Note/NoteContextTrigger.tsx b/src/components/Note/NoteContextTrigger.tsx new file mode 100644 index 0000000..ed8ec96 --- /dev/null +++ b/src/components/Note/NoteContextTrigger.tsx @@ -0,0 +1,28 @@ +import { Component } from 'solid-js'; +import { hookForDev } from '../../lib/devTools'; + +import styles from './Note.module.scss'; + + +const NoteContextTrigger: Component<{ + ref: HTMLDivElement | undefined, + id?: string, + onClick?: () => void, +}> = (props) => { + return ( +
+ +
+ ) +} + +export default hookForDev(NoteContextTrigger); diff --git a/src/components/Note/NoteFooter/NoteFooter.module.scss b/src/components/Note/NoteFooter/NoteFooter.module.scss index e491d49..f126b56 100644 --- a/src/components/Note/NoteFooter/NoteFooter.module.scss +++ b/src/components/Note/NoteFooter/NoteFooter.module.scss @@ -43,12 +43,12 @@ .footer { display: grid; - grid-template-columns: 128px 128px 128px 128px 16px; + grid-template-columns: 125px 125px 125px 125px 28px; position: relative; width: 100%; &.wide { - grid-template-columns: 140px 140px 140px 138px 16px; + grid-template-columns: 137px 137px 137px 135px 28px; } .context { diff --git a/src/components/Note/NoteFooter/NoteFooter.tsx b/src/components/Note/NoteFooter/NoteFooter.tsx index 5ad47bb..dc4e069 100644 --- a/src/components/Note/NoteFooter/NoteFooter.tsx +++ b/src/components/Note/NoteFooter/NoteFooter.tsx @@ -1,5 +1,5 @@ -import { Component, createEffect, createSignal, Show } from 'solid-js'; -import { MenuItem, PrimalNote, ZapOption } from '../../../types/primal'; +import { batch, Component, createEffect, Show } from 'solid-js'; +import { MenuItem, PrimalNote } from '../../../types/primal'; import { sendRepost } from '../../../lib/notes'; import styles from './NoteFooter.module.scss'; @@ -9,7 +9,6 @@ import { useIntl } from '@cookbook/solid-intl'; import { truncateNumber } from '../../../lib/notifications'; import { canUserReceiveZaps, zapNote } from '../../../lib/zap'; -import CustomZap from '../../CustomZap/CustomZap'; import { useSettingsContext } from '../../../contexts/SettingsContext'; import zapMD from '../../../assets/lottie/zap_md.json'; @@ -19,8 +18,19 @@ import { hookForDev } from '../../../lib/devTools'; import { getScreenCordinates } from '../../../utils'; import ZapAnimation from '../../ZapAnimation/ZapAnimation'; import { CustomZapInfo, useAppContext } from '../../../contexts/AppContext'; +import NoteFooterActionButton from './NoteFooterActionButton'; +import { NoteFooterState } from '../Note'; +import { SetStoreFunction } from 'solid-js/store'; +import BookmarkNote from '../../BookmarkNote/BookmarkNote'; -const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> = (props) => { +const NoteFooter: Component<{ + note: PrimalNote, + wide?: boolean, + id?: string, + state: NoteFooterState, + updateState: SetStoreFunction, + customZapInfo: CustomZapInfo, +}> = (props) => { const account = useAccountContext(); const toast = useToastContext(); @@ -30,28 +40,8 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> = let medZapAnimation: HTMLElement | undefined; - const [liked, setLiked] = createSignal(props.note.post.noteActions.liked); - const [zapped, setZapped] = createSignal(props.note.post.noteActions.zapped); - const [replied, setReplied] = createSignal(props.note.post.noteActions.replied); - const [reposted, setReposted] = createSignal(props.note.post.noteActions.reposted); - - const [likes, setLikes] = createSignal(props.note.post.likes); - const [reposts, setReposts] = createSignal(props.note.post.reposts); - const [replies, setReplies] = createSignal(props.note.post.replies); - const [zapCount, setZapCount] = createSignal(props.note.post.zaps); - const [zaps, setZaps] = createSignal(props.note.post.satszapped); - - const [isRepostMenuVisible, setIsRepostMenuVisible] = createSignal(false); - - const [showZapAnim, setShowZapAnim] = createSignal(false); - const [hideZapIcon, setHideZapIcon] = createSignal(false); - const [zappedNow, setZappedNow] = createSignal(false); - const [zappedAmount, setZappedAmount] = createSignal(0); - const [isZapping, setIsZapping] = createSignal(false); - let quickZapDelay = 0; let footerDiv: HTMLDivElement | undefined; - let noteContextMenu: HTMLDivElement | undefined; let repostMenu: HTMLDivElement | undefined; const repostMenuItems: MenuItem[] = [ @@ -67,17 +57,16 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> = }, ]; - const onClickOutside = (e: MouseEvent) => { if ( !document?.getElementById(`repost_menu_${props.note.post.id}`)?.contains(e.target as Node) ) { - setIsRepostMenuVisible(false); + props.updateState('isRepostMenuVisible', () => false); } } createEffect(() => { - if (isRepostMenuVisible()) { + if (props.state.isRepostMenuVisible) { document.addEventListener('click', onClickOutside); } else { @@ -87,7 +76,7 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> = const showRepostMenu = (e: MouseEvent) => { e.preventDefault(); - setIsRepostMenuVisible(true); + props.updateState('isRepostMenuVisible', () => true); }; const doQuote = () => { @@ -95,7 +84,7 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> = account?.actions.showGetStarted(); return; } - setIsRepostMenuVisible(false); + props.updateState('isRepostMenuVisible', () => false); account?.actions?.quoteNote(`nostr:${props.note.post.noteId}`); account?.actions?.showNewNoteForm(); }; @@ -117,13 +106,16 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> = return; } - setIsRepostMenuVisible(false); + props.updateState('isRepostMenuVisible', () => false); const { success } = await sendRepost(props.note, account.relays, account.relaySettings); if (success) { - setReposts(reposts() + 1); - setReposted(true); + batch(() => { + props.updateState('reposts', (r) => r + 1); + props.updateState('reposted', () => true); + }); + toast?.sendSuccess( intl.formatMessage(t.repostSuccess), ); @@ -160,63 +152,20 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> = const success = await account.actions.addLike(props.note); if (success) { - setLikes(likes() + 1); - setLiked(true); + batch(() => { + props.updateState('likes', (l) => l + 1); + props.updateState('liked', () => true); + }); } }; - const onConfirmZap = (zapOption: ZapOption) => { - app?.actions.closeCustomZapModal(); - setZappedAmount(() => zapOption.amount || 0); - setZappedNow(true); - setZapped(true); - animateZap(); - }; - - const onSuccessZap = (zapOption: ZapOption) => { - app?.actions.closeCustomZapModal(); - setIsZapping(false); - setZappedNow(false); - setShowZapAnim(false); - setHideZapIcon(false); - setZapped(true); - }; - - const onFailZap = (zapOption: ZapOption) => { - setZappedAmount(() => -(zapOption.amount || 0)); - setZappedNow(true); - app?.actions.closeCustomZapModal(); - setIsZapping(false); - setShowZapAnim(false); - setHideZapIcon(false); - setZapped(props.note.post.noteActions.zapped); - }; - - const onCancelZap = (zapOption: ZapOption) => { - setZappedAmount(() => -(zapOption.amount || 0)); - setZappedNow(true); - app?.actions.closeCustomZapModal(); - setIsZapping(false); - setShowZapAnim(false); - setHideZapIcon(false); - setZapped(props.note.post.noteActions.zapped); - }; - - const customZapInfo: CustomZapInfo = { - note: props.note, - onConfirm: onConfirmZap, - onSuccess: onSuccessZap, - onFail: onFailZap, - onCancel: onCancelZap, - }; - const startZap = (e: MouseEvent | TouchEvent) => { e.preventDefault(); e.stopPropagation(); if (!account?.hasPublicKey()) { - account?.actions.showGetStarted() - setIsZapping(false); + account?.actions.showGetStarted(); + props.updateState('isZapping', () => false); return; } @@ -231,13 +180,13 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> = toast?.sendWarning( intl.formatMessage(t.zapUnavailable), ); - setIsZapping(false); + props.updateState('isZapping', () => false); return; } quickZapDelay = setTimeout(() => { - app?.actions.openCustomZapModal(customZapInfo); - setIsZapping(true); + app?.actions.openCustomZapModal(props.customZapInfo); + props.updateState('isZapping', () => true); }, 500); }; @@ -262,9 +211,8 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> = }; const animateZap = () => { - setShowZapAnim(true); setTimeout(() => { - setHideZapIcon(true); + props.updateState('hideZapIcon', () => true); if (!medZapAnimation) { return; @@ -277,8 +225,10 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> = medZapAnimation.style.top = `${newTop}px`; const onAnimDone = () => { - setShowZapAnim(false); - setHideZapIcon(false); + batch(() => { + props.updateState('showZapAnim', () => false); + props.updateState('hideZapIcon', () => false); + }); medZapAnimation?.removeEventListener('complete', onAnimDone); } @@ -302,19 +252,24 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> = return; } - setZappedAmount(() => settings?.defaultZap.amount || 0); - setZappedNow(true); - animateZap(); + batch(() => { + props.updateState('zappedAmount', () => settings?.defaultZap.amount || 0); + props.updateState('zappedNow', () => true); + props.updateState('showZapAnim', () => true); + }); const success = await zapNote(props.note, account.publicKey, settings?.defaultZap.amount || 10, settings?.defaultZap.message || '', account.relays); - setIsZapping(false); + + props.updateState('isZapping', () => false); if (success) { return; } - setZappedAmount(() => -(settings?.defaultZap.amount || 0)); - setZappedNow(true); - setZapped(props.note.post.noteActions.zapped); + batch(() => { + props.updateState('zappedAmount', () => -(settings?.defaultZap.amount || 0)); + props.updateState('zappedNow', () => true); + props.updateState('zapped', () => props.note.post.noteActions.zapped); + }); } const buttonTypeClasses: Record = { @@ -324,51 +279,21 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> = repost: styles.repostType, }; - const actionButton = (opts: { - type: 'zap' | 'like' | 'reply' | 'repost', - disabled?: boolean, - highlighted?: boolean, - onClick?: (e: MouseEvent) => void, - onMouseDown?: (e: MouseEvent) => void, - onMouseUp?: (e: MouseEvent) => void, - onTouchStart?: (e: TouchEvent) => void, - onTouchEnd?: (e: TouchEvent) => void, - label: string | number, - hidden?: boolean, - title?: string, - }) => { - - return ( - - ); - }; + createEffect(() => { + if (props.state.zappedNow) { + batch(() => { + props.updateState('zapCount', (z) => z + 1); + props.updateState('satsZapped', (z) => z + props.state.zappedAmount); + props.updateState('zapped', () => true); + }); + props.updateState('zappedNow', () => false); + } + }); createEffect(() => { - - if (zappedNow()) { - setZapCount(c => c + 1); - setZaps((z) => z + zappedAmount()); - setZapped(true); - setZappedNow(false); + if (props.state.showZapAnim) { + animateZap(); } - }); const determineOrient = () => { @@ -380,7 +305,7 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> = return (
{e.preventDefault();}}> - + = /> - {actionButton({ - onClick: doReply, - type: 'reply', - highlighted: replied(), - label: replies() === 0 ? '' : truncateNumber(replies(), 2), - title: replies().toLocaleString(), - })} + - {actionButton({ - onClick: (e: MouseEvent) => e.preventDefault(), - onMouseDown: startZap, - onMouseUp: commitZap, - onTouchStart: startZap, - onTouchEnd: commitZap, - type: 'zap', - highlighted: zapped() || isZapping(), - label: zaps() === 0 ? '' : truncateNumber(zaps(), 2), - hidden: hideZapIcon(), - title: zaps().toLocaleString(), - })} - - {actionButton({ - onClick: doLike, - type: 'like', - highlighted: liked(), - label: likes() === 0 ? '' : truncateNumber(likes(), 2), - title: likes().toLocaleString(), - })} + e.preventDefault()} + onMouseDown={startZap} + onMouseUp={commitZap} + onTouchStart={startZap} + onTouchEnd={commitZap} + type="zap" + highlighted={props.state.zapped || props.state.isZapping} + label={props.state.satsZapped === 0 ? '' : truncateNumber(props.state.satsZapped, 2)} + hidden={props.state.hideZapIcon} + title={props.state.satsZapped.toLocaleString()} + /> +
-
- -
) } diff --git a/src/components/Note/NoteFooter/NoteFooterActionButton.tsx b/src/components/Note/NoteFooter/NoteFooterActionButton.tsx new file mode 100644 index 0000000..d9377ce --- /dev/null +++ b/src/components/Note/NoteFooter/NoteFooterActionButton.tsx @@ -0,0 +1,50 @@ +import { Component, createEffect, onCleanup } from 'solid-js'; +import { PrimalNote } from '../../../types/primal'; + +import styles from './NoteFooter.module.scss'; + +const buttonTypeClasses: Record = { + zap: styles.zapType, + like: styles.likeType, + reply: styles.replyType, + repost: styles.repostType, +}; + +const NoteFooterActionButton: Component<{ + type: 'zap' | 'like' | 'reply' | 'repost', + note: PrimalNote, + disabled?: boolean, + highlighted?: boolean, + onClick?: (e: MouseEvent) => void, + onMouseDown?: (e: MouseEvent) => void, + onMouseUp?: (e: MouseEvent) => void, + onTouchStart?: (e: TouchEvent) => void, + onTouchEnd?: (e: TouchEvent) => void, + label: string | number, + hidden?: boolean, + title?: string, +}> = (props) => { + + return ( + + ) +} + +export default NoteFooterActionButton; diff --git a/src/components/Notifications/NotificationItem.module.scss b/src/components/Notifications/NotificationItem.module.scss index 0ff7842..888529c 100644 --- a/src/components/Notifications/NotificationItem.module.scss +++ b/src/components/Notifications/NotificationItem.module.scss @@ -5,7 +5,7 @@ padding-top: 12px; padding-bottom: 17px; - border-bottom: 1px solid var(--subtile-devider); + border-bottom: 1px solid var(--devider); .newBubble { position: absolute; diff --git a/src/components/Notifications/NotificationItem.tsx b/src/components/Notifications/NotificationItem.tsx index a227d9e..3024fe9 100644 --- a/src/components/Notifications/NotificationItem.tsx +++ b/src/components/Notifications/NotificationItem.tsx @@ -33,6 +33,7 @@ import NotificationNote from '../Note/NotificationNote/NotificationNote'; import NotificationAvatar from '../NotificationAvatar/NotificationAvatar'; import { notificationsNew as t } from '../../translations'; import { hookForDev } from '../../lib/devTools'; +import Note from '../Note/Note'; const typeIcons: Record = { [NotificationType.NEW_USER_FOLLOWED_YOU]: userFollow, @@ -183,9 +184,10 @@ const NotificationItem: Component = (props) => { >
-
diff --git a/src/components/Notifications/NotificationItemOld.tsx b/src/components/Notifications/NotificationItemOld.tsx index 2bc5f4f..7fc7882 100644 --- a/src/components/Notifications/NotificationItemOld.tsx +++ b/src/components/Notifications/NotificationItemOld.tsx @@ -33,6 +33,7 @@ import NotificationNote from '../Note/NotificationNote/NotificationNote'; import { truncateNumber } from '../../lib/notifications'; import { notificationsOld as t } from '../../translations'; import { hookForDev } from '../../lib/devTools'; +import Note from '../Note/Note'; const typeIcons: Record = { [NotificationType.NEW_USER_FOLLOWED_YOU]: userFollow, @@ -148,9 +149,10 @@ const NotificationItemOld: Component = (props) => { >
-
diff --git a/src/lib/feed.ts b/src/lib/feed.ts index 9dfaa91..a8efa0d 100644 --- a/src/lib/feed.ts +++ b/src/lib/feed.ts @@ -72,7 +72,14 @@ export const getUserFeed = (user_pubkey: string | undefined, pubkey: string | un return; } - let payload = { pubkey, limit, notes } ; + let payload: { + pubkey: string, + limit: number, + notes: 'authored' | 'replies' | 'bookmarks', + user_pubkey?: string, + until?: number, + offset?: number, + } = { pubkey, limit, notes } ; if (user_pubkey) { payload.user_pubkey = user_pubkey; diff --git a/src/pages/Notifications.module.scss b/src/pages/Notifications.module.scss index 407dbac..d8867da 100644 --- a/src/pages/Notifications.module.scss +++ b/src/pages/Notifications.module.scss @@ -6,7 +6,7 @@ .oldNotifications { position: relative; - padding-right: 2px; + // padding-right: 2px; } .loader { @@ -62,28 +62,6 @@ } -@media only screen and (max-width: 1300px) { - .newContentNotification { - left: calc(calc(100vw - 1032px) / 2 + 48px + 32px); - } -} - -@media only screen and (max-width: 1087px) { - .newContentNotification { - left: calc(calc(100vw - 720px) / 2 + 48px + 32px); - } -} - -@media only screen and (max-width: 720px) { - .newContentNotification { - left: 0; - width: 100%; - justify-content: center; - } -} - - - .notificationTabs { position: relative; display: flex; @@ -122,7 +100,7 @@ } .notificationTabContent { - width: 100%; + width: 602px; } .notificationTabIndicator { @@ -148,3 +126,27 @@ border-radius: 0 0 8px 8px; padding-top: 22px; } + +@media only screen and (max-width: 1300px) { + .newContentNotification { + left: calc(calc(100vw - 1032px) / 2 + 48px + 32px); + } +} + +@media only screen and (max-width: 1087px) { + .newContentNotification { + left: calc(calc(100vw - 720px) / 2 + 48px + 32px); + } +} + +@media only screen and (max-width: 720px) { + .newContentNotification { + left: 0; + width: 100%; + justify-content: center; + } + + .notificationTabContent { + width: 100%; + } +} diff --git a/src/pages/Thread.tsx b/src/pages/Thread.tsx index d3cca34..cb3eca5 100644 --- a/src/pages/Thread.tsx +++ b/src/pages/Thread.tsx @@ -195,8 +195,9 @@ const Thread: Component = () => { }>
-