parent
c515e9837d
commit
f2319b074f
@ -1,24 +1,23 @@
|
||||
import { HexKey } from "@snort/system";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import useModeration from "@/Hooks/useModeration";
|
||||
|
||||
import messages from "../messages";
|
||||
import AsyncButton from "../Button/AsyncButton";
|
||||
|
||||
interface MuteButtonProps {
|
||||
pubkey: HexKey;
|
||||
pubkey: string;
|
||||
}
|
||||
|
||||
const MuteButton = ({ pubkey }: MuteButtonProps) => {
|
||||
const { mute, unmute, isMuted } = useModeration();
|
||||
return isMuted(pubkey) ? (
|
||||
<button className="secondary" type="button" onClick={() => unmute(pubkey)}>
|
||||
<FormattedMessage {...messages.Unmute} />
|
||||
</button>
|
||||
<AsyncButton className="secondary" type="button" onClick={() => unmute(pubkey)}>
|
||||
<FormattedMessage defaultMessage="Unmute" />
|
||||
</AsyncButton>
|
||||
) : (
|
||||
<button type="button" onClick={() => mute(pubkey)}>
|
||||
<FormattedMessage {...messages.Mute} />
|
||||
</button>
|
||||
<AsyncButton type="button" onClick={() => mute(pubkey)}>
|
||||
<FormattedMessage defaultMessage="Mute" />
|
||||
</AsyncButton>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -4,7 +4,10 @@ import { EventKind, NostrEvent, NostrLink, TaggedNostrEvent, ToNostrEventTag, Un
|
||||
import useLogin from "@/Hooks/useLogin";
|
||||
|
||||
export class MutedWordTag implements ToNostrEventTag {
|
||||
constructor(readonly word: string) {}
|
||||
constructor(readonly word: string) { }
|
||||
equals(other: ToNostrEventTag): boolean {
|
||||
return other instanceof MutedWordTag && other.word === this.word;
|
||||
}
|
||||
|
||||
toEventTag(): string[] | undefined {
|
||||
return ["word", this.word.toLowerCase()];
|
||||
@ -16,7 +19,7 @@ export default function useModeration() {
|
||||
|
||||
function isMuted(id: string) {
|
||||
const link = NostrLink.publicKey(id);
|
||||
return state.muted.includes(link);
|
||||
return state.muted.some(a => a.equals(link));
|
||||
}
|
||||
|
||||
async function unmute(id: string) {
|
||||
|
@ -15,9 +15,11 @@ import Avatar from "@/Components/User/Avatar";
|
||||
import FollowButton from "@/Components/User/FollowButton";
|
||||
import ProfileImage from "@/Components/User/ProfileImage";
|
||||
import ZapModal from "@/Components/ZapModal/ZapModal";
|
||||
import useModeration from "@/Hooks/useModeration";
|
||||
import { hexToBech32 } from "@/Utils";
|
||||
import { LoginSessionType, LoginStore } from "@/Utils/Login";
|
||||
import { ZapTarget } from "@/Utils/Zapper";
|
||||
import MuteButton from "@/Components/User/MuteButton";
|
||||
|
||||
const AvatarSection = ({
|
||||
user,
|
||||
@ -36,11 +38,14 @@ const AvatarSection = ({
|
||||
const [modalImage, setModalImage] = useState<string>("");
|
||||
const [showLnQr, setShowLnQr] = useState<boolean>(false);
|
||||
const [prefix, setPrefix] = useState<NostrPrefix>(CONFIG.profileLinkPrefix);
|
||||
|
||||
const { mute, unmute, isMuted } = useModeration();
|
||||
const navigate = useNavigate();
|
||||
const relays = UserRelays.getFromCache(id);
|
||||
const isMe = loginPubKey === id;
|
||||
const canWrite = !!loginPubKey && !readonly;
|
||||
const intl = useIntl();
|
||||
const muted = id ? isMuted(id) : false;
|
||||
|
||||
const profileId = useMemo(() => {
|
||||
if (!id) return;
|
||||
@ -107,6 +112,19 @@ const AvatarSection = ({
|
||||
icon={{ name: "envelope", size: 16 }}
|
||||
/>
|
||||
)}
|
||||
{canWrite && muted && <MuteButton pubkey={id} />}
|
||||
{canWrite && !muted && <IconButton
|
||||
className={muted ? "bg-success" : "!bg-error"}
|
||||
onClick={async () => {
|
||||
if (muted) {
|
||||
await unmute(id);
|
||||
} else {
|
||||
await mute(id);
|
||||
}
|
||||
}}
|
||||
icon={{ name: "mute", size: 16 }}
|
||||
/>
|
||||
}
|
||||
{!canWrite && !isMe && (
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
|
@ -59,15 +59,6 @@ const ProfileTabSelectors = {
|
||||
),
|
||||
value: ProfileTabType.MUTED,
|
||||
},
|
||||
Blocked: {
|
||||
text: (
|
||||
<>
|
||||
<Icon name="block" size={16} />
|
||||
<FormattedMessage defaultMessage="Blocked" />
|
||||
</>
|
||||
),
|
||||
value: ProfileTabType.BLOCKED,
|
||||
},
|
||||
Relays: {
|
||||
text: (
|
||||
<>
|
||||
|
@ -16,6 +16,8 @@ module.exports = {
|
||||
"nostr-red": "var(--heart)",
|
||||
"nostr-purple": "var(--highlight)",
|
||||
secondary: "var(--font-secondary-color)",
|
||||
"warning": "var(--warning)",
|
||||
"error": "var(--error)"
|
||||
},
|
||||
spacing: {
|
||||
px: "1px",
|
||||
|
@ -101,11 +101,7 @@ export class DiffSyncTags extends EventEmitter<SafeSyncEvents> {
|
||||
|
||||
async sync(signer: EventSigner | undefined, system: SystemInterface) {
|
||||
await this.#sync.sync(system);
|
||||
|
||||
if (this.#sync.value?.content && this.contentEncrypted && signer) {
|
||||
const decrypted = await signer.nip4Decrypt(this.#sync.value.content, await signer.getPubKey());
|
||||
this.#decryptedContent = decrypted;
|
||||
}
|
||||
await this.#afterSync(signer);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,6 +119,15 @@ export class DiffSyncTags extends EventEmitter<SafeSyncEvents> {
|
||||
next.content = await signer.nip4Encrypt(next.content, await signer.getPubKey());
|
||||
}
|
||||
await this.#sync.update(next, signer, system, !isNew);
|
||||
await this.#afterSync(signer);
|
||||
}
|
||||
|
||||
async #afterSync(signer: EventSigner | undefined) {
|
||||
if (this.#sync.value?.content && this.contentEncrypted && signer) {
|
||||
const decrypted = await signer.nip4Decrypt(this.#sync.value.content, await signer.getPubKey());
|
||||
this.#decryptedContent = decrypted;
|
||||
this.emit("change");
|
||||
}
|
||||
}
|
||||
|
||||
#nextEvent(content?: string): NotSignedNostrEvent {
|
||||
@ -141,6 +146,7 @@ export class DiffSyncTags extends EventEmitter<SafeSyncEvents> {
|
||||
// apply changes onto next
|
||||
next.tags = this.#applyChanges(next.tags, this.#changes);
|
||||
if (this.#changesEncrypted.length > 0 && !content) {
|
||||
debugger;
|
||||
const encryptedTags = this.#applyChanges(isNew ? [] : this.encryptedTags, this.#changesEncrypted);
|
||||
next.content = JSON.stringify(encryptedTags);
|
||||
} else if (content) {
|
||||
|
@ -117,12 +117,13 @@ export class UserState<TAppData> extends EventEmitter<UserStateEvents> {
|
||||
}
|
||||
await Promise.all(tasks);
|
||||
this.#log(
|
||||
"Init results: profile=%O, contacts=%O, relays=%O, appdata=%O, lists=%O",
|
||||
"Init results: signer=%s, profile=%O, contacts=%O, relays=%O, appdata=%O, lists=%O",
|
||||
signer ? "yes" : "no",
|
||||
this.#profile.json,
|
||||
this.#contacts.value,
|
||||
this.#relays.value,
|
||||
this.#appdata?.json,
|
||||
[...this.#standardLists.values()].map(a => a.value),
|
||||
[...this.#standardLists.values()].map(a => [a.value, a.encryptedTags]),
|
||||
);
|
||||
|
||||
// update relay metadata with value from contact list if not found
|
||||
|
Loading…
x
Reference in New Issue
Block a user