mirror of
https://github.com/PrimalHQ/primal-web-app.git
synced 2024-10-01 17:31:13 +00:00
Unify context menu and fix mute/unmute and report actions
This commit is contained in:
parent
1fe6b2851b
commit
29461e4e96
@ -19,6 +19,7 @@ import Landing from '../../pages/Landing';
|
||||
import ReactionsModal from '../ReactionsModal/ReactionsModal';
|
||||
import { useAppContext } from '../../contexts/AppContext';
|
||||
import CustomZap from '../CustomZap/CustomZap';
|
||||
import NoteContextMenu from '../Note/NoteContextMenu';
|
||||
|
||||
export const [isHome, setIsHome] = createSignal(false);
|
||||
|
||||
@ -183,6 +184,11 @@ const Layout: Component = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<NoteContextMenu
|
||||
open={app?.showNoteContextMenu}
|
||||
onClose={app?.actions.closeContextMenu}
|
||||
data={app?.noteContextMenuInfo}
|
||||
/>
|
||||
</>
|
||||
</Show>
|
||||
)
|
||||
|
@ -185,46 +185,46 @@
|
||||
}
|
||||
}
|
||||
|
||||
.contextButton {
|
||||
width: 16px;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.contextMenu {
|
||||
position: relative;
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
|
||||
.contextButton {
|
||||
width: 16px;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,11 +22,13 @@ import { reportUser } from '../../lib/profile';
|
||||
import { useToastContext } from '../Toaster/Toaster';
|
||||
import { broadcastEvent } from '../../lib/notes';
|
||||
import { getScreenCordinates } from '../../utils';
|
||||
import { NoteContextMenuInfo } from '../../contexts/AppContext';
|
||||
import ConfirmModal from '../ConfirmModal/ConfirmModal';
|
||||
|
||||
const NoteContextMenu: Component<{
|
||||
note: PrimalNote,
|
||||
openCustomZap?: () => void;
|
||||
openReactions?: () => void,
|
||||
data: NoteContextMenuInfo,
|
||||
open: boolean,
|
||||
onClose: () => void,
|
||||
id?: string,
|
||||
}> = (props) => {
|
||||
const account = useAccountContext();
|
||||
@ -37,62 +39,95 @@ const NoteContextMenu: Component<{
|
||||
const [confirmReportUser, setConfirmReportUser] = createSignal(false);
|
||||
const [confirmMuteUser, setConfirmMuteUser] = createSignal(false);
|
||||
|
||||
const openContextMenu = (e: MouseEvent) => {
|
||||
e.preventDefault();
|
||||
setContext(true);
|
||||
const [orientation, setOrientation] = createSignal<'down' | 'up'>('down')
|
||||
|
||||
const note = () => props.data?.note;
|
||||
const position = () => {
|
||||
return props.data?.position;
|
||||
};
|
||||
const openCustomZap = props.data?.openCustomZap || (() => {});
|
||||
const openReactions = props.data?.openReactions || (() => {});
|
||||
|
||||
createEffect(() => {
|
||||
if(!context) return;
|
||||
|
||||
if (!props.open) {
|
||||
context.setAttribute('style',`top: -1024px; left: -1034px;`);
|
||||
}
|
||||
|
||||
const docRect = document.documentElement.getBoundingClientRect();
|
||||
const pos = {
|
||||
top: (Math.floor(position()?.top || 0) - docRect.top),
|
||||
left: (Math.floor(position()?.left || 0)),
|
||||
}
|
||||
|
||||
context.setAttribute('style',`top: ${pos.top + 12}px; left: ${pos.left + 12}px;`);
|
||||
|
||||
const height = 440;
|
||||
const orient = Math.floor(position()?.bottom || 0) + height < window.innerHeight ? 'down' : 'up';
|
||||
|
||||
setOrientation(() => orient);
|
||||
});
|
||||
|
||||
|
||||
const doMuteUser = () => {
|
||||
account?.actions.addToMuteList(props.note.post.pubkey);
|
||||
account?.actions.addToMuteList(note()?.post.pubkey);
|
||||
props.onClose();
|
||||
};
|
||||
|
||||
const doUnmuteUser = () => {
|
||||
account?.actions.removeFromMuteList(props.note.post.pubkey);
|
||||
account?.actions.removeFromMuteList(note()?.post.pubkey);
|
||||
props.onClose();
|
||||
};
|
||||
|
||||
const doReportUser = () => {
|
||||
reportUser(props.note.user.pubkey, `report_user_${APP_ID}`, props.note.user);
|
||||
setContext(false);
|
||||
toaster?.sendSuccess(intl.formatMessage(tToast.noteAuthorReported, { name: userName(props.note.user)}));
|
||||
reportUser(note()?.user.pubkey, `report_user_${APP_ID}`, note()?.user);
|
||||
props.onClose();
|
||||
toaster?.sendSuccess(intl.formatMessage(tToast.noteAuthorReported, { name: userName(note()?.user)}));
|
||||
};
|
||||
|
||||
const copyNoteLink = () => {
|
||||
navigator.clipboard.writeText(`${window.location.origin}/e/${props.note.post.noteId}`);
|
||||
setContext(false);
|
||||
if (!props.data) return;
|
||||
navigator.clipboard.writeText(`${window.location.origin}/e/${note().post.noteId}`);
|
||||
props.onClose()
|
||||
toaster?.sendSuccess(intl.formatMessage(tToast.notePrimalLinkCoppied));
|
||||
};
|
||||
|
||||
const copyNoteText = () => {
|
||||
navigator.clipboard.writeText(`${props.note.post.content}`);
|
||||
setContext(false);
|
||||
if (!props.data) return;
|
||||
navigator.clipboard.writeText(`${note().post.content}`);
|
||||
props.onClose()
|
||||
toaster?.sendSuccess(intl.formatMessage(tToast.notePrimalTextCoppied));
|
||||
};
|
||||
|
||||
const copyNoteId = () => {
|
||||
navigator.clipboard.writeText(`${props.note.post.noteId}`);
|
||||
setContext(false);
|
||||
if (!props.data) return;
|
||||
navigator.clipboard.writeText(`${note().post.noteId}`);
|
||||
props.onClose()
|
||||
toaster?.sendSuccess(intl.formatMessage(tToast.noteIdCoppied));
|
||||
};
|
||||
|
||||
const copyRawData = () => {
|
||||
navigator.clipboard.writeText(`${JSON.stringify(props.note.msg)}`);
|
||||
setContext(false);
|
||||
if (!props.data) return;
|
||||
navigator.clipboard.writeText(`${JSON.stringify(note().msg)}`);
|
||||
props.onClose()
|
||||
toaster?.sendSuccess(intl.formatMessage(tToast.noteRawDataCoppied));
|
||||
};
|
||||
|
||||
const copyUserNpub = () => {
|
||||
navigator.clipboard.writeText(`${props.note.user.npub}`);
|
||||
setContext(false);
|
||||
if (!props.data) return;
|
||||
navigator.clipboard.writeText(`${note().user.npub}`);
|
||||
props.onClose()
|
||||
toaster?.sendSuccess(intl.formatMessage(tToast.noteAuthorNpubCoppied));
|
||||
};
|
||||
|
||||
const broadcastNote = async () => {
|
||||
if (!account) {
|
||||
if (!account || !props.data) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { success } = await broadcastEvent(props.note.msg as NostrRelaySignedEvent, account?.relays, account?.relaySettings);
|
||||
setContext(false);
|
||||
const { success } = await broadcastEvent(note().msg as NostrRelaySignedEvent, account?.relays, account?.relaySettings);
|
||||
props.onClose()
|
||||
|
||||
if (success) {
|
||||
toaster?.sendSuccess(intl.formatMessage(tToast.noteBroadcastSuccess));
|
||||
@ -103,14 +138,15 @@ const NoteContextMenu: Component<{
|
||||
|
||||
const onClickOutside = (e: MouseEvent) => {
|
||||
if (
|
||||
!document?.getElementById(`note_context_${props.note.post.id}`)?.contains(e.target as Node)
|
||||
!props.data ||
|
||||
!document?.getElementById(`note_context_${note().post.id}`)?.contains(e.target as Node)
|
||||
) {
|
||||
setContext(false);
|
||||
props.onClose()
|
||||
}
|
||||
}
|
||||
|
||||
createEffect(() => {
|
||||
if (showContext()) {
|
||||
if (props.open) {
|
||||
document.addEventListener('click', onClickOutside);
|
||||
}
|
||||
else {
|
||||
@ -119,24 +155,24 @@ const NoteContextMenu: Component<{
|
||||
});
|
||||
|
||||
const isVerifiedByPrimal = () => {
|
||||
return !!props.note.user.nip05 &&
|
||||
props.note.user.nip05.endsWith('primal.net');
|
||||
return props.data && !!note().user.nip05 &&
|
||||
note().user.nip05.endsWith('primal.net');
|
||||
}
|
||||
|
||||
const noteContextForEveryone: MenuItem[] = [
|
||||
{
|
||||
label: intl.formatMessage(tActions.noteContext.reactions),
|
||||
action: () => {
|
||||
props.openReactions && props.openReactions();
|
||||
setContext(false);
|
||||
openReactions();
|
||||
props.onClose()
|
||||
},
|
||||
icon: 'heart',
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(tActions.noteContext.zap),
|
||||
action: () => {
|
||||
props.openCustomZap && props.openCustomZap();
|
||||
setContext(false);
|
||||
openCustomZap();
|
||||
props.onClose()
|
||||
},
|
||||
icon: 'feed_zap',
|
||||
},
|
||||
@ -172,53 +208,65 @@ const NoteContextMenu: Component<{
|
||||
},
|
||||
];
|
||||
|
||||
const noteContextForOtherPeople: MenuItem[] = [
|
||||
{
|
||||
label: intl.formatMessage(tActions.noteContext.muteAuthor),
|
||||
action: () => {
|
||||
setConfirmMuteUser(true);
|
||||
setContext(false);
|
||||
},
|
||||
icon: 'mute_user',
|
||||
warning: true,
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(tActions.noteContext.reportAuthor),
|
||||
action: () => {
|
||||
setConfirmReportUser(true);
|
||||
setContext(false);
|
||||
},
|
||||
icon: 'report',
|
||||
warning: true,
|
||||
},
|
||||
];
|
||||
const noteContextForOtherPeople: () => MenuItem[] = () => {
|
||||
const isMuted = account?.muted.includes(note()?.user.pubkey);
|
||||
|
||||
const noteContext = account?.publicKey !== props.note.post.pubkey ?
|
||||
[ ...noteContextForEveryone, ...noteContextForOtherPeople] :
|
||||
return [
|
||||
{
|
||||
label: isMuted ? intl.formatMessage(tActions.noteContext.unmuteAuthor) : intl.formatMessage(tActions.noteContext.muteAuthor),
|
||||
action: () => {
|
||||
isMuted ? doUnmuteUser() : setConfirmMuteUser(true);
|
||||
props.onClose()
|
||||
},
|
||||
icon: 'mute_user',
|
||||
warning: true,
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(tActions.noteContext.reportAuthor),
|
||||
action: () => {
|
||||
setConfirmReportUser(true);
|
||||
props.onClose()
|
||||
},
|
||||
icon: 'report',
|
||||
warning: true,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
const noteContext = () => account?.publicKey !== note()?.post.pubkey ?
|
||||
[ ...noteContextForEveryone, ...noteContextForOtherPeople()] :
|
||||
noteContextForEveryone;
|
||||
|
||||
let context: HTMLDivElement | undefined;
|
||||
|
||||
const determineOrient = () => {
|
||||
const coor = getScreenCordinates(context);
|
||||
const height = 440;
|
||||
return (coor.y || 0) + height < window.innerHeight + window.scrollY ? 'down' : 'up';
|
||||
}
|
||||
|
||||
return (
|
||||
<div class={styles.contextMenu} ref={context}>
|
||||
<button
|
||||
class={styles.contextButton}
|
||||
onClick={openContextMenu}
|
||||
>
|
||||
<div class={styles.contextIcon} ></div>
|
||||
</button>
|
||||
<ConfirmModal
|
||||
open={confirmReportUser()}
|
||||
description={intl.formatMessage(tActions.reportUserConfirm, { name: authorName(note()?.user) })}
|
||||
onConfirm={() => {
|
||||
doReportUser();
|
||||
setConfirmReportUser(false);
|
||||
}}
|
||||
onAbort={() => setConfirmReportUser(false)}
|
||||
/>
|
||||
|
||||
<ConfirmModal
|
||||
open={confirmMuteUser()}
|
||||
description={intl.formatMessage(tActions.muteUserConfirm, { name: authorName(note()?.user) })}
|
||||
onConfirm={() => {
|
||||
doMuteUser();
|
||||
setConfirmMuteUser(false);
|
||||
}}
|
||||
onAbort={() => setConfirmMuteUser(false)}
|
||||
/>
|
||||
|
||||
<PrimalMenu
|
||||
id={`note_context_${props.note.post.id}`}
|
||||
items={noteContext}
|
||||
hidden={!showContext()}
|
||||
id={`note_context_${note()?.post.id}`}
|
||||
items={noteContext()}
|
||||
hidden={!props.open}
|
||||
position="note_footer"
|
||||
orientation={determineOrient()}
|
||||
orientation={orientation()}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@ -9,6 +9,38 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.contextButton {
|
||||
width: 48px;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: grid;
|
||||
grid-template-columns: 128px 128px 128px 128px 16px;
|
||||
|
@ -46,6 +46,7 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> =
|
||||
const [isRepostMenuVisible, setIsRepostMenuVisible] = createSignal(false);
|
||||
|
||||
let footerDiv: HTMLDivElement | undefined;
|
||||
let noteContextMenu: HTMLDivElement | undefined;
|
||||
|
||||
const repostMenuItems: MenuItem[] = [
|
||||
{
|
||||
@ -374,7 +375,7 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> =
|
||||
}
|
||||
|
||||
return (
|
||||
<div id={props.id} class={`${styles.footer} ${props.wide ? styles.wide : ''}`} ref={footerDiv}>
|
||||
<div id={props.id} class={`${styles.footer} ${props.wide ? styles.wide : ''}`} ref={footerDiv} onClick={(e) => {e.preventDefault();}}>
|
||||
|
||||
<Show when={showZapAnim()}>
|
||||
<ZapAnimation
|
||||
@ -442,21 +443,32 @@ const NoteFooter: Component<{ note: PrimalNote, wide?: boolean, id?: string }> =
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div class={styles.context}>
|
||||
<NoteContextMenu
|
||||
note={props.note}
|
||||
openCustomZap={() => {
|
||||
app?.actions.openCustomZapModal(customZapInfo);
|
||||
<div ref={noteContextMenu} class={styles.context}>
|
||||
<button
|
||||
class={styles.contextButton}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
app?.actions.openContextMenu(
|
||||
props.note,
|
||||
noteContextMenu?.getBoundingClientRect(),
|
||||
() => {
|
||||
app?.actions.openCustomZapModal(customZapInfo);
|
||||
},
|
||||
() => {
|
||||
app?.actions.openReactionModal(props.note.post.id, {
|
||||
likes: likes(),
|
||||
zaps: zapCount(),
|
||||
reposts: reposts(),
|
||||
quotes: 0,
|
||||
});
|
||||
}
|
||||
);
|
||||
}}
|
||||
openReactions={() => {
|
||||
app?.actions.openReactionModal(props.note.post.id, {
|
||||
likes: likes(),
|
||||
zaps: zapCount(),
|
||||
reposts: reposts(),
|
||||
quotes: 0,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
>
|
||||
<div class={styles.contextIcon} ></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
@ -32,6 +32,8 @@ const ProfileTabs: Component<{
|
||||
const profile = useProfileContext();
|
||||
const account = useAccountContext();
|
||||
|
||||
const [currentTab, setCurrentTab] = createSignal<string>('notes');
|
||||
|
||||
const addToAllowlist = async () => {
|
||||
const pk = profile?.profileKey;
|
||||
if (pk) {
|
||||
@ -58,7 +60,10 @@ const ProfileTabs: Component<{
|
||||
return;
|
||||
}
|
||||
|
||||
account.actions.removeFromMuteList(pk);
|
||||
account.actions.removeFromMuteList(pk, () => {
|
||||
props.setProfile && props.setProfile(pk);
|
||||
onChangeValue(currentTab());
|
||||
});
|
||||
};
|
||||
|
||||
const onContactAction = (remove: boolean, pubkey: string) => {
|
||||
@ -125,6 +130,8 @@ const ProfileTabs: Component<{
|
||||
const onChangeValue = (value: string) => {
|
||||
if (!profile) return;
|
||||
|
||||
setCurrentTab(() => value);
|
||||
|
||||
switch(value) {
|
||||
case 'notes':
|
||||
profile.notes.length === 0 && profile.actions.fetchNotes(profile.profileKey);
|
||||
|
@ -25,6 +25,13 @@ export type CustomZapInfo = {
|
||||
onCancel: (zapOption: ZapOption) => void,
|
||||
};
|
||||
|
||||
export type NoteContextMenuInfo = {
|
||||
note: PrimalNote,
|
||||
position: DOMRect | undefined,
|
||||
openCustomZap?: () => void,
|
||||
openReactions?: () => void,
|
||||
};
|
||||
|
||||
export type AppContextStore = {
|
||||
isInactive: boolean,
|
||||
appState: 'sleep' | 'waking' | 'woke',
|
||||
@ -32,11 +39,15 @@ export type AppContextStore = {
|
||||
reactionStats: ReactionStats,
|
||||
showCustomZapModal: boolean,
|
||||
customZap: CustomZapInfo | undefined,
|
||||
showNoteContextMenu: boolean,
|
||||
noteContextMenuInfo: NoteContextMenuInfo | undefined,
|
||||
actions: {
|
||||
openReactionModal: (noteId: string, stats: ReactionStats) => void,
|
||||
closeReactionModal: () => void,
|
||||
openCustomZapModal: (custonZapInfo: CustomZapInfo) => void,
|
||||
closeCustomZapModal: () => void,
|
||||
openContextMenu: (note: PrimalNote, position: DOMRect | undefined, openCustomZapModal: () => void, openReactionModal: () => void) => void,
|
||||
closeContextMenu: () => void,
|
||||
},
|
||||
}
|
||||
|
||||
@ -52,6 +63,8 @@ const initialData: Omit<AppContextStore, 'actions'> = {
|
||||
},
|
||||
showCustomZapModal: false,
|
||||
customZap: undefined,
|
||||
showNoteContextMenu: false,
|
||||
noteContextMenuInfo: undefined,
|
||||
};
|
||||
|
||||
export const AppContext = createContext<AppContextStore>();
|
||||
@ -96,6 +109,20 @@ export const AppProvider = (props: { children: JSXElement }) => {
|
||||
updateStore('showCustomZapModal', () => false);
|
||||
};
|
||||
|
||||
const openContextMenu = (note: PrimalNote, position: DOMRect | undefined, openCustomZapModal: () => void, openReactionModal: () => void) => {
|
||||
updateStore('noteContextMenuInfo', reconcile({
|
||||
note,
|
||||
position,
|
||||
openCustomZapModal,
|
||||
openReactionModal,
|
||||
}))
|
||||
updateStore('showNoteContextMenu', () => true);
|
||||
};
|
||||
|
||||
const closeContextMenu = () => {
|
||||
updateStore('showNoteContextMenu', () => false);
|
||||
};
|
||||
|
||||
// EFFECTS --------------------------------------
|
||||
|
||||
onMount(() => {
|
||||
@ -138,6 +165,8 @@ export const AppProvider = (props: { children: JSXElement }) => {
|
||||
closeReactionModal,
|
||||
openCustomZapModal,
|
||||
closeCustomZapModal,
|
||||
openContextMenu,
|
||||
closeContextMenu,
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -128,6 +128,7 @@ export type ProfileContextStore = {
|
||||
fetchFollowerList: (pubkey: string | undefined) => void,
|
||||
fetchRelayList: (pubkey: string | undefined) => void,
|
||||
clearContacts: () => void,
|
||||
clearFilterReason: () => void,
|
||||
removeContact: (pubkey: string) => void,
|
||||
addContact: (pubkey: string, source: PrimalUser[]) => void,
|
||||
fetchZapList: (pubkey: string | undefined) => void,
|
||||
@ -514,6 +515,10 @@ export const ProfileProvider = (props: { children: ContextChildren }) => {
|
||||
updateStore('profileStats', () => ({}));
|
||||
};
|
||||
|
||||
const clearFilterReason = () => {
|
||||
updateStore('filterReason', () => null);
|
||||
};
|
||||
|
||||
const fetchNextPage = () => {
|
||||
const lastNote = store.notes[store.notes.length - 1];
|
||||
|
||||
@ -1018,6 +1023,8 @@ export const ProfileProvider = (props: { children: ContextChildren }) => {
|
||||
|
||||
if (reason?.action === 'block') {
|
||||
updateStore('filterReason', () => ({ ...reason }));
|
||||
} else {
|
||||
updateStore('filterReason', () => null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1229,6 +1236,7 @@ export const ProfileProvider = (props: { children: ContextChildren }) => {
|
||||
fetchNextZapsPage,
|
||||
clearZaps,
|
||||
resetProfile,
|
||||
clearFilterReason,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -121,6 +121,7 @@ const Profile: Component = () => {
|
||||
profile?.actions.clearReplies();
|
||||
profile?.actions.clearContacts();
|
||||
profile?.actions.clearZaps();
|
||||
profile?.actions.clearFilterReason();
|
||||
}
|
||||
|
||||
let keyIsDone = false
|
||||
@ -416,7 +417,6 @@ const Profile: Component = () => {
|
||||
toaster?.sendSuccess(intl.formatMessage(tToast.noteAuthorReported, { name: userName(profile?.userProfile)}));
|
||||
};
|
||||
|
||||
|
||||
const addToAllowlist = async () => {
|
||||
const pk = getHex();
|
||||
if (pk) {
|
||||
@ -679,7 +679,7 @@ const Profile: Component = () => {
|
||||
</Show>
|
||||
</div>
|
||||
|
||||
<ProfileTabs />
|
||||
<ProfileTabs setProfile={setProfile} />
|
||||
|
||||
<ConfirmModal
|
||||
open={confirmReportUser()}
|
||||
|
@ -405,6 +405,11 @@ export const actions = {
|
||||
defaultMessage: 'Mute user',
|
||||
description: 'Label for muting user from context menu',
|
||||
},
|
||||
unmuteAuthor: {
|
||||
id: 'actions.noteContext.unmuteAuthor',
|
||||
defaultMessage: 'Unmute user',
|
||||
description: 'Label for unmuting user from context menu',
|
||||
},
|
||||
reportAuthor: {
|
||||
id: 'actions.noteContext.reportAuthor',
|
||||
defaultMessage: 'Report user',
|
||||
|
Loading…
Reference in New Issue
Block a user