'init'
This commit is contained in:
36
app/components/UserMention/UserMention.module.css
Normal file
36
app/components/UserMention/UserMention.module.css
Normal file
@@ -0,0 +1,36 @@
|
||||
@keyframes failVibrate {
|
||||
0%, 100% {
|
||||
left: 0px;
|
||||
}
|
||||
20%, 60% {
|
||||
left: -2px;
|
||||
}
|
||||
40%, 80% {
|
||||
left: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes skeletonPulse {
|
||||
0% {
|
||||
color: var(--mantine-primary-color-0);
|
||||
}
|
||||
50% {
|
||||
color: var(--mantine-primary-color-2);
|
||||
}
|
||||
100% {
|
||||
color: var(--mantine-primary-color-0);
|
||||
}
|
||||
}
|
||||
|
||||
.mention {
|
||||
user-select: auto;
|
||||
}
|
||||
|
||||
.skeleton {
|
||||
animation: skeletonPulse 1.5s infinite;
|
||||
}
|
||||
|
||||
.fail_vibrate {
|
||||
position: relative;
|
||||
animation: failVibrate 0.3s linear;
|
||||
}
|
||||
86
app/components/UserMention/UserMention.tsx
Normal file
86
app/components/UserMention/UserMention.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
import { usePrivateKeyHash } from "@/app/providers/AccountProvider/usePrivateKeyHash";
|
||||
import { PacketSearch, PacketSearchUser } from "@/app/providers/ProtocolProvider/protocol/packets/packet.search";
|
||||
import { usePacket } from "@/app/providers/ProtocolProvider/usePacket";
|
||||
import { useSender } from "@/app/providers/ProtocolProvider/useSender";
|
||||
import { Anchor } from "@mantine/core";
|
||||
import { useState } from "react";
|
||||
import classes from './UserMention.module.css';
|
||||
import { cx } from "@/app/utils/style";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
export interface UserMentionProps {
|
||||
username: string;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export function UserMention(props : UserMentionProps) {
|
||||
const send = useSender();
|
||||
const privateKey = usePrivateKeyHash();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [fail, setFail] = useState(false);
|
||||
const [vibrate, setVibrate] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
usePacket(0x03, (packet: PacketSearch) => {
|
||||
if(!loading){
|
||||
return;
|
||||
}
|
||||
if(fail){
|
||||
vibrateCall();
|
||||
return;
|
||||
}
|
||||
setLoading(false);
|
||||
let users = packet.getUsers();
|
||||
if(users.length <= 0){
|
||||
vibrateCall();
|
||||
setFail(true);
|
||||
return;
|
||||
}
|
||||
const user = findMatchuser(users);
|
||||
if(!user){
|
||||
vibrateCall();
|
||||
setFail(true);
|
||||
return;
|
||||
}
|
||||
navigate(`/main/chat/${user.publicKey}`);
|
||||
}, [props.username, loading, fail]);
|
||||
|
||||
const findMatchuser = (users: PacketSearchUser[]) => {
|
||||
for(let user of users){
|
||||
if(user.username === props.username.replace('@', '')){
|
||||
return user;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const onClick = () => {
|
||||
if(fail){
|
||||
vibrateCall();
|
||||
return;
|
||||
}
|
||||
let packet = new PacketSearch();
|
||||
packet.setSearch(props.username.replace('@', ''));
|
||||
packet.setPrivateKey(privateKey);
|
||||
send(packet);
|
||||
setLoading(true);
|
||||
}
|
||||
|
||||
const vibrateCall = () => {
|
||||
if(vibrate){
|
||||
return;
|
||||
}
|
||||
setVibrate(true);
|
||||
setTimeout(() => {
|
||||
setVibrate(false);
|
||||
}, 300);
|
||||
}
|
||||
|
||||
return (
|
||||
<Anchor className={cx(
|
||||
classes.mention,
|
||||
loading && classes.skeleton,
|
||||
vibrate && classes.fail_vibrate
|
||||
)} onClick={onClick} c={props.color} size="sm">{props.username}</Anchor>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user