mirror of
https://github.com/cheeaun/phanpy.git
synced 2025-03-30 05:09:18 +03:00
New account context menu!
Add Mention, Mute and Block
This commit is contained in:
parent
51bc920ada
commit
24fdaf78d1
5 changed files with 348 additions and 68 deletions
20
src/app.css
20
src/app.css
|
@ -1077,8 +1077,10 @@ body:has(.status-deck) .media-post-link {
|
||||||
max-width: 90vw;
|
max-width: 90vw;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.szh-menu__item--focusable {
|
.szh-menu[aria-label='Submenu'] {
|
||||||
background-color: transparent;
|
background-color: var(--bg-blur-color);
|
||||||
|
backdrop-filter: blur(4px);
|
||||||
|
box-shadow: 0 3px 24px -3px var(--drop-shadow-color);
|
||||||
}
|
}
|
||||||
.szh-menu__header {
|
.szh-menu__header {
|
||||||
margin: -8px 0 8px;
|
margin: -8px 0 8px;
|
||||||
|
@ -1098,7 +1100,7 @@ body:has(.status-deck) .media-post-link {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
line-height: 1;
|
line-height: 1.1;
|
||||||
padding: 8px 16px !important;
|
padding: 8px 16px !important;
|
||||||
transition: all 0.1s ease-in-out;
|
transition: all 0.1s ease-in-out;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
@ -1106,6 +1108,9 @@ body:has(.status-deck) .media-post-link {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
.szh-menu .szh-menu__item--focusable {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
.szh-menu .szh-menu__item span {
|
.szh-menu .szh-menu__item span {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -1186,6 +1191,15 @@ body:has(.status-deck) .media-post-link {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.szh-menu .menu-wrap {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.szh-menu .menu-wrap > * {
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-basis: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
/* GLASS MENU */
|
/* GLASS MENU */
|
||||||
|
|
||||||
.glass-menu {
|
.glass-menu {
|
||||||
|
|
|
@ -158,6 +158,9 @@
|
||||||
.account-container .actions button {
|
.account-container .actions button {
|
||||||
align-self: flex-end;
|
align-self: flex-end;
|
||||||
}
|
}
|
||||||
|
.account-container .actions .buttons {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
.account-container .profile-metadata {
|
.account-container .profile-metadata {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
import './account-info.css';
|
import './account-info.css';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Menu,
|
||||||
|
MenuDivider,
|
||||||
|
MenuHeader,
|
||||||
|
MenuItem,
|
||||||
|
SubMenu,
|
||||||
|
} from '@szhsin/react-menu';
|
||||||
import { useEffect, useRef, useState } from 'preact/hooks';
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
||||||
|
|
||||||
import RelativeTime from '../components/relative-time';
|
import RelativeTime from '../components/relative-time';
|
||||||
|
@ -9,6 +16,7 @@ import enhanceContent from '../utils/enhance-content';
|
||||||
import handleContentLinks from '../utils/handle-content-links';
|
import handleContentLinks from '../utils/handle-content-links';
|
||||||
import niceDateTime from '../utils/nice-date-time';
|
import niceDateTime from '../utils/nice-date-time';
|
||||||
import shortenNumber from '../utils/shorten-number';
|
import shortenNumber from '../utils/shorten-number';
|
||||||
|
import showToast from '../utils/show-toast';
|
||||||
import states, { hideAllModals } from '../utils/states';
|
import states, { hideAllModals } from '../utils/states';
|
||||||
import store from '../utils/store';
|
import store from '../utils/store';
|
||||||
|
|
||||||
|
@ -17,6 +25,27 @@ import Avatar from './avatar';
|
||||||
import Icon from './icon';
|
import Icon from './icon';
|
||||||
import Link from './link';
|
import Link from './link';
|
||||||
|
|
||||||
|
const MUTE_DURATIONS = [
|
||||||
|
1000 * 60 * 5, // 5 minutes
|
||||||
|
1000 * 60 * 30, // 30 minutes
|
||||||
|
1000 * 60 * 60, // 1 hour
|
||||||
|
1000 * 60 * 60 * 6, // 6 hours
|
||||||
|
1000 * 60 * 60 * 24, // 1 day
|
||||||
|
1000 * 60 * 60 * 24 * 3, // 3 days
|
||||||
|
1000 * 60 * 60 * 24 * 7, // 1 week
|
||||||
|
0, // forever
|
||||||
|
];
|
||||||
|
const MUTE_DURATIONS_LABELS = {
|
||||||
|
0: 'Forever',
|
||||||
|
300_000: '5 minutes',
|
||||||
|
1_800_000: '30 minutes',
|
||||||
|
3_600_000: '1 hour',
|
||||||
|
21_600_000: '6 hours',
|
||||||
|
86_400_000: '1 day',
|
||||||
|
259_200_000: '3 days',
|
||||||
|
604_800_000: '1 week',
|
||||||
|
};
|
||||||
|
|
||||||
function AccountInfo({
|
function AccountInfo({
|
||||||
account,
|
account,
|
||||||
fetchAccount = () => {},
|
fetchAccount = () => {},
|
||||||
|
@ -360,7 +389,7 @@ function RelatedActions({ info, instance, authenticated }) {
|
||||||
const [relationship, setRelationship] = useState(null);
|
const [relationship, setRelationship] = useState(null);
|
||||||
const [familiarFollowers, setFamiliarFollowers] = useState([]);
|
const [familiarFollowers, setFamiliarFollowers] = useState([]);
|
||||||
|
|
||||||
const { id, locked, lastStatusAt } = info;
|
const { id, acct, url, username, locked, lastStatusAt } = info;
|
||||||
const accountID = useRef(id);
|
const accountID = useRef(id);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -445,6 +474,8 @@ function RelatedActions({ info, instance, authenticated }) {
|
||||||
}
|
}
|
||||||
}, [info, authenticated]);
|
}, [info, authenticated]);
|
||||||
|
|
||||||
|
const loading = relationshipUIState === 'loading';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{familiarFollowers?.length > 0 && (
|
{familiarFollowers?.length > 0 && (
|
||||||
|
@ -481,65 +512,277 @@ function RelatedActions({ info, instance, authenticated }) {
|
||||||
Last status: <RelativeTime datetime={lastStatusAt} format="micro" />
|
Last status: <RelativeTime datetime={lastStatusAt} format="micro" />
|
||||||
</span>
|
</span>
|
||||||
)}{' '}
|
)}{' '}
|
||||||
{relationshipUIState !== 'loading' && relationship && (
|
<span class="buttons">
|
||||||
<button
|
<Menu
|
||||||
type="button"
|
portal={{
|
||||||
class={`${following || requested ? 'light swap' : ''}`}
|
target: document.body,
|
||||||
data-swap-state={following || requested ? 'danger' : ''}
|
}}
|
||||||
disabled={relationshipUIState === 'loading'}
|
containerProps={{
|
||||||
onClick={() => {
|
style: {
|
||||||
setRelationshipUIState('loading');
|
// Higher than the backdrop
|
||||||
|
zIndex: 1001,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
align="center"
|
||||||
|
position="anchor"
|
||||||
|
overflow="auto"
|
||||||
|
boundingBoxPadding="8 8 8 8"
|
||||||
|
menuButton={
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
title="More"
|
||||||
|
class="plain"
|
||||||
|
disabled={loading}
|
||||||
|
>
|
||||||
|
<Icon icon="more" size="l" alt="More" />
|
||||||
|
</button>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{currentAuthenticated && (
|
||||||
|
<>
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
states.showCompose = {
|
||||||
|
draftStatus: {
|
||||||
|
status: `@${acct} `,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon icon="at" />
|
||||||
|
<span>Mention @{username}</span>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuDivider />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
<MenuItem href={url} target="_blank">
|
||||||
|
<Icon icon="external" />
|
||||||
|
<small class="menu-double-lines">{niceAccountURL(url)}</small>
|
||||||
|
</MenuItem>
|
||||||
|
<div class="menu-horizontal">
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
// Copy url to clipboard
|
||||||
|
try {
|
||||||
|
navigator.clipboard.writeText(url);
|
||||||
|
showToast('Link copied');
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
showToast('Unable to copy link');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon icon="link" />
|
||||||
|
<span>Copy</span>
|
||||||
|
</MenuItem>
|
||||||
|
{navigator?.share &&
|
||||||
|
navigator?.canShare?.({
|
||||||
|
url,
|
||||||
|
}) && (
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
try {
|
||||||
|
navigator.share({
|
||||||
|
url,
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
alert("Sharing doesn't seem to work.");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon icon="share" />
|
||||||
|
<span>Share…</span>
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{!!relationship && (
|
||||||
|
<>
|
||||||
|
<MenuDivider />
|
||||||
|
{muting ? (
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
setRelationshipUIState('loading');
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const newRelationship =
|
||||||
|
await currentMasto.v1.accounts.unmute(id);
|
||||||
|
console.log('unmuting', newRelationship);
|
||||||
|
setRelationship(newRelationship);
|
||||||
|
setRelationshipUIState('default');
|
||||||
|
showToast(`Unmuted @${username}`);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
setRelationshipUIState('error');
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon icon="unmute" />
|
||||||
|
<span>Unmute @{username}</span>
|
||||||
|
</MenuItem>
|
||||||
|
) : (
|
||||||
|
<SubMenu
|
||||||
|
openTrigger="clickOnly"
|
||||||
|
direction="bottom"
|
||||||
|
overflow="auto"
|
||||||
|
offsetX={-16}
|
||||||
|
label={
|
||||||
|
<>
|
||||||
|
<Icon icon="mute" />
|
||||||
|
<span class="menu-grow">Mute @{username}…</span>
|
||||||
|
<span>
|
||||||
|
<Icon icon="time" />
|
||||||
|
<Icon icon="chevron-right" />
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div class="menu-wrap">
|
||||||
|
{MUTE_DURATIONS.map((duration) => (
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
setRelationshipUIState('loading');
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const newRelationship =
|
||||||
|
await currentMasto.v1.accounts.mute(id, {
|
||||||
|
duration,
|
||||||
|
});
|
||||||
|
console.log('muting', newRelationship);
|
||||||
|
setRelationship(newRelationship);
|
||||||
|
setRelationshipUIState('default');
|
||||||
|
showToast(
|
||||||
|
`Muted @${username} for ${MUTE_DURATIONS_LABELS[duration]}`,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
setRelationshipUIState('error');
|
||||||
|
showToast(`Unable to mute @${username}`);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{MUTE_DURATIONS_LABELS[duration]}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</SubMenu>
|
||||||
|
)}
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
if (!blocking && !confirm(`Block @${username}?`)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setRelationshipUIState('loading');
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
if (blocking) {
|
||||||
|
const newRelationship =
|
||||||
|
await currentMasto.v1.accounts.unblock(id);
|
||||||
|
console.log('unblocking', newRelationship);
|
||||||
|
setRelationship(newRelationship);
|
||||||
|
setRelationshipUIState('default');
|
||||||
|
showToast(`Unblocked @${username}`);
|
||||||
|
} else {
|
||||||
|
const newRelationship =
|
||||||
|
await currentMasto.v1.accounts.block(id);
|
||||||
|
console.log('blocking', newRelationship);
|
||||||
|
setRelationship(newRelationship);
|
||||||
|
setRelationshipUIState('default');
|
||||||
|
showToast(`Blocked @${username}`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
setRelationshipUIState('error');
|
||||||
|
if (blocking) {
|
||||||
|
showToast(`Unable to unblock @${username}`);
|
||||||
|
} else {
|
||||||
|
showToast(`Unable to block @${username}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{blocking ? (
|
||||||
|
<>
|
||||||
|
<Icon icon="unblock" />
|
||||||
|
<span>Unblock @{username}</span>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Icon icon="block" />
|
||||||
|
<span>Block @{username}…</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</MenuItem>
|
||||||
|
{/* <MenuItem>
|
||||||
|
<Icon icon="flag" />
|
||||||
|
<span>Report @{username}…</span>
|
||||||
|
</MenuItem> */}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Menu>
|
||||||
|
{!!relationship && (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class={`${following || requested ? 'light swap' : ''}`}
|
||||||
|
data-swap-state={following || requested ? 'danger' : ''}
|
||||||
|
disabled={loading}
|
||||||
|
onClick={() => {
|
||||||
|
setRelationshipUIState('loading');
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
let newRelationship;
|
||||||
|
|
||||||
(async () => {
|
if (following || requested) {
|
||||||
try {
|
const yes = confirm(
|
||||||
let newRelationship;
|
requested
|
||||||
|
? 'Withdraw follow request?'
|
||||||
|
: `Unfollow @${info.acct || info.username}?`,
|
||||||
|
);
|
||||||
|
|
||||||
if (following || requested) {
|
if (yes) {
|
||||||
const yes = confirm(
|
newRelationship =
|
||||||
requested
|
await currentMasto.v1.accounts.unfollow(
|
||||||
? 'Withdraw follow request?'
|
accountID.current,
|
||||||
: `Unfollow @${info.acct || info.username}?`,
|
);
|
||||||
);
|
}
|
||||||
|
} else {
|
||||||
if (yes) {
|
newRelationship = await currentMasto.v1.accounts.follow(
|
||||||
newRelationship = await currentMasto.v1.accounts.unfollow(
|
|
||||||
accountID.current,
|
accountID.current,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
newRelationship = await currentMasto.v1.accounts.follow(
|
|
||||||
accountID.current,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newRelationship) setRelationship(newRelationship);
|
if (newRelationship) setRelationship(newRelationship);
|
||||||
setRelationshipUIState('default');
|
setRelationshipUIState('default');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert(e);
|
alert(e);
|
||||||
setRelationshipUIState('error');
|
setRelationshipUIState('error');
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{following ? (
|
{following ? (
|
||||||
<>
|
<>
|
||||||
<span>Following</span>
|
<span>Following</span>
|
||||||
<span>Unfollow…</span>
|
<span>Unfollow…</span>
|
||||||
</>
|
</>
|
||||||
) : requested ? (
|
) : requested ? (
|
||||||
<>
|
<>
|
||||||
<span>Requested</span>
|
<span>Requested</span>
|
||||||
<span>Withdraw…</span>
|
<span>Withdraw…</span>
|
||||||
</>
|
</>
|
||||||
) : locked ? (
|
) : locked ? (
|
||||||
<>
|
<>
|
||||||
<Icon icon="lock" /> <span>Follow</span>
|
<Icon icon="lock" /> <span>Follow</span>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
'Follow'
|
'Follow'
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -561,4 +804,18 @@ function lightenRGB([r, g, b]) {
|
||||||
return [r, g, b, alpha];
|
return [r, g, b, alpha];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function niceAccountURL(url) {
|
||||||
|
if (!url) return;
|
||||||
|
const urlObj = new URL(url);
|
||||||
|
const { host, pathname } = urlObj;
|
||||||
|
const path = pathname.replace(/\/$/, '').replace(/^\//, '');
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<span class="more-insignificant">{host}/</span>
|
||||||
|
<wbr />
|
||||||
|
<span>{path}</span>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default AccountInfo;
|
export default AccountInfo;
|
||||||
|
|
|
@ -244,12 +244,12 @@ function Compose({
|
||||||
textareaRef.current.value = status;
|
textareaRef.current.value = status;
|
||||||
oninputTextarea();
|
oninputTextarea();
|
||||||
focusTextarea();
|
focusTextarea();
|
||||||
spoilerTextRef.current.value = spoilerText;
|
if (spoilerText) spoilerTextRef.current.value = spoilerText;
|
||||||
setVisibility(visibility);
|
if (visibility) setVisibility(visibility);
|
||||||
setLanguage(language || prefs.postingDefaultLanguage || DEFAULT_LANG);
|
setLanguage(language || prefs.postingDefaultLanguage || DEFAULT_LANG);
|
||||||
setSensitive(sensitive);
|
if (sensitive !== null) setSensitive(sensitive);
|
||||||
setPoll(composablePoll);
|
if (composablePoll) setPoll(composablePoll);
|
||||||
setMediaAttachments(mediaAttachments);
|
if (mediaAttachments) setMediaAttachments(mediaAttachments);
|
||||||
}
|
}
|
||||||
}, [draftStatus, editStatus, replyToStatus]);
|
}, [draftStatus, editStatus, replyToStatus]);
|
||||||
|
|
||||||
|
@ -442,10 +442,6 @@ function Compose({
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleItems = (e) => {
|
const handleItems = (e) => {
|
||||||
if (mediaAttachments.length >= maxMediaAttachments) {
|
|
||||||
alert(`You can only attach up to ${maxMediaAttachments} files.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { items } = e.clipboardData || e.dataTransfer;
|
const { items } = e.clipboardData || e.dataTransfer;
|
||||||
const files = [];
|
const files = [];
|
||||||
for (let i = 0; i < items.length; i++) {
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
@ -457,6 +453,10 @@ function Compose({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (files.length > 0 && mediaAttachments.length >= maxMediaAttachments) {
|
||||||
|
alert(`You can only attach up to ${maxMediaAttachments} files.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
console.log({ files });
|
console.log({ files });
|
||||||
if (files.length > 0) {
|
if (files.length > 0) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -895,7 +895,7 @@ function Compose({
|
||||||
? 'Edit your status'
|
? 'Edit your status'
|
||||||
: 'What are you doing?'
|
: 'What are you doing?'
|
||||||
}
|
}
|
||||||
required={mediaAttachments.length === 0}
|
required={mediaAttachments?.length === 0}
|
||||||
disabled={uiState === 'loading'}
|
disabled={uiState === 'loading'}
|
||||||
lang={language}
|
lang={language}
|
||||||
onInput={() => {
|
onInput={() => {
|
||||||
|
@ -906,7 +906,7 @@ function Compose({
|
||||||
return masto.v2.search(params);
|
return masto.v2.search(params);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{mediaAttachments.length > 0 && (
|
{mediaAttachments?.length > 0 && (
|
||||||
<div class="media-attachments">
|
<div class="media-attachments">
|
||||||
{mediaAttachments.map((attachment, i) => {
|
{mediaAttachments.map((attachment, i) => {
|
||||||
const { id, file } = attachment;
|
const { id, file } = attachment;
|
||||||
|
|
|
@ -66,6 +66,12 @@ const ICONS = {
|
||||||
translate: 'mingcute:translate-line',
|
translate: 'mingcute:translate-line',
|
||||||
play: 'mingcute:play-fill',
|
play: 'mingcute:play-fill',
|
||||||
trash: 'mingcute:delete-2-line',
|
trash: 'mingcute:delete-2-line',
|
||||||
|
mute: 'mingcute:volume-mute-line',
|
||||||
|
unmute: 'mingcute:volume-line',
|
||||||
|
block: 'mingcute:forbid-circle-line',
|
||||||
|
unblock: ['mingcute:forbid-circle-line', '180deg'],
|
||||||
|
flag: 'mingcute:flag-4-line',
|
||||||
|
time: 'mingcute:time-line',
|
||||||
};
|
};
|
||||||
|
|
||||||
const modules = import.meta.glob('/node_modules/@iconify-icons/mingcute/*.js');
|
const modules = import.meta.glob('/node_modules/@iconify-icons/mingcute/*.js');
|
||||||
|
|
Loading…
Add table
Reference in a new issue