mirror of
https://github.com/revoltchat/revite.git
synced 2024-12-24 22:52:09 -05:00
Add dayjs language defaults.
Add remove / block user confirmation.
This commit is contained in:
parent
7982489ab6
commit
a569f41d1c
7 changed files with 79 additions and 31 deletions
2
external/lang
vendored
2
external/lang
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 4ef73335436f3118d660cec24ff7972d3ccd5984
|
Subproject commit e200511dcb2c655e6ee89580fee9ef96c9f1f387
|
|
@ -125,10 +125,34 @@ function Locale({ children, locale }: Props) {
|
||||||
const [defns, setDefinition] = useState(definition);
|
const [defns, setDefinition] = useState(definition);
|
||||||
const lang = Languages[locale];
|
const lang = Languages[locale];
|
||||||
|
|
||||||
|
function transformLanguage(obj: { [key: string]: any }) {
|
||||||
|
const dayjs = obj.dayjs;
|
||||||
|
const defaults = dayjs.defaults;
|
||||||
|
|
||||||
|
const twelvehour = defaults?.twelvehour === 'yes' || true;
|
||||||
|
const separator: '/' | '-' | '.' = defaults?.date_separator ?? '/';
|
||||||
|
const date: 'traditional' | 'simplified' | 'ISO8601' = defaults?.date_format ?? 'traditional';
|
||||||
|
|
||||||
|
const DATE_FORMATS = {
|
||||||
|
traditional: `DD${separator}MM${separator}YYYY`,
|
||||||
|
simplified: `MM${separator}DD${separator}YYYY`,
|
||||||
|
ISO8601: 'YYYY-MM-DD'
|
||||||
|
}
|
||||||
|
|
||||||
|
dayjs['sameElse'] = DATE_FORMATS[date];
|
||||||
|
Object.keys(dayjs)
|
||||||
|
.filter(k => k !== 'defaults')
|
||||||
|
.forEach(k => dayjs[k] = dayjs[k].replace(/{{time}}/g, twelvehour ? 'LT' : 'HH:mm'));
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (locale === "en") {
|
if (locale === "en") {
|
||||||
|
transformLanguage(definition);
|
||||||
setDefinition(definition);
|
setDefinition(definition);
|
||||||
dayjs.locale("en");
|
dayjs.locale("en");
|
||||||
|
dayjs.updateLocale('en', { calendar: definition.dayjs });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,6 +165,7 @@ function Locale({ children, locale }: Props) {
|
||||||
import(`../../external/lang/${lang.i18n}.json`).then(
|
import(`../../external/lang/${lang.i18n}.json`).then(
|
||||||
async (lang_file) => {
|
async (lang_file) => {
|
||||||
const defn = lang_file.default;
|
const defn = lang_file.default;
|
||||||
|
transformLanguage(defn);
|
||||||
const target = lang.dayjs ?? lang.i18n;
|
const target = lang.dayjs ?? lang.i18n;
|
||||||
const dayjs_locale = await import(`../../node_modules/dayjs/esm/locale/${target}.js`);
|
const dayjs_locale = await import(`../../node_modules/dayjs/esm/locale/${target}.js`);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Attachment, Channels, EmbedImage, Servers } from "revolt.js/dist/api/objects";
|
import { Attachment, Channels, EmbedImage, Servers, Users } from "revolt.js/dist/api/objects";
|
||||||
import { useContext, useEffect, useMemo, useState } from "preact/hooks";
|
import { useContext, useEffect, useMemo, useState } from "preact/hooks";
|
||||||
import { internalSubscribe } from "../../lib/eventEmitter";
|
import { internalSubscribe } from "../../lib/eventEmitter";
|
||||||
import { Action } from "../../components/ui/Modal";
|
import { Action } from "../../components/ui/Modal";
|
||||||
|
@ -26,6 +26,8 @@ export type Screen =
|
||||||
{ type: "create_invite", target: Channels.TextChannel | Channels.GroupChannel } |
|
{ type: "create_invite", target: Channels.TextChannel | Channels.GroupChannel } |
|
||||||
{ type: "kick_member", target: Servers.Server, user: string } |
|
{ type: "kick_member", target: Servers.Server, user: string } |
|
||||||
{ type: "ban_member", target: Servers.Server, user: string } |
|
{ type: "ban_member", target: Servers.Server, user: string } |
|
||||||
|
{ type: "unfriend_user", target: Users.User } |
|
||||||
|
{ type: "block_user", target: Users.User } |
|
||||||
{ type: "create_channel", target: Servers.Server }
|
{ type: "create_channel", target: Servers.Server }
|
||||||
)) |
|
)) |
|
||||||
({ id: "special_input" } & (
|
({ id: "special_input" } & (
|
||||||
|
|
|
@ -35,6 +35,7 @@ export function InputModal({
|
||||||
disabled={processing}
|
disabled={processing}
|
||||||
actions={[
|
actions={[
|
||||||
{
|
{
|
||||||
|
confirmation: true,
|
||||||
text: <Text id="app.special.modals.actions.ok" />,
|
text: <Text id="app.special.modals.actions.ok" />,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
setProcessing(true);
|
setProcessing(true);
|
||||||
|
|
|
@ -10,10 +10,11 @@ import Overline from "../../../components/ui/Overline";
|
||||||
import { AppContext } from "../../revoltjs/RevoltClient";
|
import { AppContext } from "../../revoltjs/RevoltClient";
|
||||||
import { mapMessage, takeError } from "../../revoltjs/util";
|
import { mapMessage, takeError } from "../../revoltjs/util";
|
||||||
import Modal, { Action } from "../../../components/ui/Modal";
|
import Modal, { Action } from "../../../components/ui/Modal";
|
||||||
import { Channels, Servers } from "revolt.js/dist/api/objects";
|
import { Channels, Servers, Users } from "revolt.js/dist/api/objects";
|
||||||
import { useContext, useEffect, useState } from "preact/hooks";
|
import { useContext, useEffect, useState } from "preact/hooks";
|
||||||
import UserIcon from "../../../components/common/user/UserIcon";
|
import UserIcon from "../../../components/common/user/UserIcon";
|
||||||
import Message from "../../../components/common/messaging/Message";
|
import Message from "../../../components/common/messaging/Message";
|
||||||
|
import { TextReact } from "../../../lib/i18n";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
@ -48,6 +49,8 @@ type SpecialProps = { onClose: () => void } & (
|
||||||
{ type: "create_invite", target: Channels.TextChannel | Channels.GroupChannel } |
|
{ type: "create_invite", target: Channels.TextChannel | Channels.GroupChannel } |
|
||||||
{ type: "kick_member", target: Servers.Server, user: string } |
|
{ type: "kick_member", target: Servers.Server, user: string } |
|
||||||
{ type: "ban_member", target: Servers.Server, user: string } |
|
{ type: "ban_member", target: Servers.Server, user: string } |
|
||||||
|
{ type: "unfriend_user", target: Users.User } |
|
||||||
|
{ type: "block_user", target: Users.User } |
|
||||||
{ type: "create_channel", target: Servers.Server }
|
{ type: "create_channel", target: Servers.Server }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -62,23 +65,33 @@ export function SpecialPromptModal(props: SpecialProps) {
|
||||||
case 'close_dm':
|
case 'close_dm':
|
||||||
case 'leave_server':
|
case 'leave_server':
|
||||||
case 'delete_server':
|
case 'delete_server':
|
||||||
case 'delete_channel': {
|
case 'delete_channel':
|
||||||
|
case 'unfriend_user':
|
||||||
|
case 'block_user': {
|
||||||
const EVENTS = {
|
const EVENTS = {
|
||||||
'close_dm': 'confirm_close_dm',
|
'close_dm': ['confirm_close_dm', 'close'],
|
||||||
'delete_server': 'confirm_delete',
|
'delete_server': ['confirm_delete', 'delete'],
|
||||||
'delete_channel': 'confirm_delete',
|
'delete_channel': ['confirm_delete', 'delete'],
|
||||||
'leave_group': 'confirm_leave',
|
'leave_group': ['confirm_leave', 'leave'],
|
||||||
'leave_server': 'confirm_leave'
|
'leave_server': ['confirm_leave', 'leave'],
|
||||||
|
'unfriend_user': ['unfriend_user', 'remove'],
|
||||||
|
'block_user': ['block_user', 'block']
|
||||||
};
|
};
|
||||||
|
|
||||||
let event = EVENTS[props.type];
|
let event = EVENTS[props.type];
|
||||||
let name = props.type === 'close_dm' ? client.users.get(client.channels.getRecipient(props.target._id))?.username : props.target.name;
|
let name;
|
||||||
|
switch (props.type) {
|
||||||
|
case 'unfriend_user':
|
||||||
|
case 'block_user': name = props.target.username; break;
|
||||||
|
case 'close_dm': name = client.users.get(client.channels.getRecipient(props.target._id))?.username; break;
|
||||||
|
default: name = props.target.name;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PromptModal
|
<PromptModal
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
question={<Text
|
question={<Text
|
||||||
id={`app.special.modals.prompt.${event}`}
|
id={`app.special.modals.prompt.${event[0]}`}
|
||||||
fields={{ name }}
|
fields={{ name }}
|
||||||
/>}
|
/>}
|
||||||
actions={[
|
actions={[
|
||||||
|
@ -86,15 +99,23 @@ export function SpecialPromptModal(props: SpecialProps) {
|
||||||
confirmation: true,
|
confirmation: true,
|
||||||
contrast: true,
|
contrast: true,
|
||||||
error: true,
|
error: true,
|
||||||
text: <Text id="app.special.modals.actions.delete" />,
|
text: <Text id={`app.special.modals.actions.${event[1]}`} />,
|
||||||
onClick: async () => {
|
onClick: async () => {
|
||||||
setProcessing(true);
|
setProcessing(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (props.type === 'leave_group' || props.type === 'close_dm' || props.type === 'delete_channel') {
|
switch (props.type) {
|
||||||
await client.channels.delete(props.target._id);
|
case 'unfriend_user':
|
||||||
} else {
|
await client.users.removeFriend(props.target._id); break;
|
||||||
await client.servers.delete(props.target._id);
|
case 'block_user':
|
||||||
|
await client.users.blockUser(props.target._id); break;
|
||||||
|
case 'leave_group':
|
||||||
|
case 'close_dm':
|
||||||
|
case 'delete_channel':
|
||||||
|
await client.channels.delete(props.target._id); break;
|
||||||
|
case 'leave_server':
|
||||||
|
case 'delete_server':
|
||||||
|
await client.servers.delete(props.target._id); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose();
|
onClose();
|
||||||
|
@ -106,7 +127,7 @@ export function SpecialPromptModal(props: SpecialProps) {
|
||||||
},
|
},
|
||||||
{ text: <Text id="app.special.modals.actions.cancel" />, onClick: onClose }
|
{ text: <Text id="app.special.modals.actions.cancel" />, onClick: onClose }
|
||||||
]}
|
]}
|
||||||
content={<Text id={`app.special.modals.prompt.${event}_long`} />}
|
content={<TextReact id={`app.special.modals.prompt.${event[0]}_long`} fields={{ name: <b>{ name }</b> }} />}
|
||||||
disabled={processing}
|
disabled={processing}
|
||||||
error={error}
|
error={error}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -60,11 +60,11 @@ type Action =
|
||||||
| { action: "ban_member"; target: Servers.Server; user: string }
|
| { action: "ban_member"; target: Servers.Server; user: string }
|
||||||
| { action: "view_profile"; user: string }
|
| { action: "view_profile"; user: string }
|
||||||
| { action: "message_user"; user: string }
|
| { action: "message_user"; user: string }
|
||||||
| { action: "block_user"; user: string }
|
| { action: "block_user"; user: Users.User }
|
||||||
| { action: "unblock_user"; user: string }
|
| { action: "unblock_user"; user: Users.User }
|
||||||
| { action: "add_friend"; user: string }
|
| { action: "add_friend"; user: Users.User }
|
||||||
| { action: "remove_friend"; user: string }
|
| { action: "remove_friend"; user: Users.User }
|
||||||
| { action: "cancel_friend"; user: string }
|
| { action: "cancel_friend"; user: Users.User }
|
||||||
| { action: "set_presence"; presence: Users.Presence }
|
| { action: "set_presence"; presence: Users.Presence }
|
||||||
| { action: "set_status" }
|
| { action: "set_status" }
|
||||||
| { action: "clear_status" }
|
| { action: "clear_status" }
|
||||||
|
@ -264,22 +264,21 @@ function ContextMenus(props: Props) {
|
||||||
|
|
||||||
case "add_friend":
|
case "add_friend":
|
||||||
{
|
{
|
||||||
let user = client.users.get(data.user);
|
await client.users.addFriend(data.user.username);
|
||||||
if (user) {
|
|
||||||
await client.users.addFriend(user.username);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "block_user":
|
case "block_user":
|
||||||
await client.users.blockUser(data.user);
|
openScreen({ id: 'special_prompt', type: 'block_user', target: data.user });
|
||||||
break;
|
break;
|
||||||
case "unblock_user":
|
case "unblock_user":
|
||||||
await client.users.unblockUser(data.user);
|
await client.users.unblockUser(data.user._id);
|
||||||
break;
|
break;
|
||||||
case "remove_friend":
|
case "remove_friend":
|
||||||
|
openScreen({ id: 'special_prompt', type: 'unfriend_user', target: data.user });
|
||||||
|
break;
|
||||||
case "cancel_friend":
|
case "cancel_friend":
|
||||||
await client.users.removeFriend(data.user);
|
await client.users.removeFriend(data.user._id);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "set_presence":
|
case "set_presence":
|
||||||
|
@ -466,7 +465,7 @@ function ContextMenus(props: Props) {
|
||||||
for (const action of actions) {
|
for (const action of actions) {
|
||||||
generateAction({
|
generateAction({
|
||||||
action: action as any,
|
action: action as any,
|
||||||
user: user._id
|
user
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ export function Friend({ user }: Props) {
|
||||||
actions.push(
|
actions.push(
|
||||||
<IconButton type="circle"
|
<IconButton type="circle"
|
||||||
className={classNames(styles.button, styles.error)}
|
className={classNames(styles.button, styles.error)}
|
||||||
onClick={ev => stopPropagation(ev, client.users.removeFriend(user._id))}>
|
onClick={ev => stopPropagation(ev, openScreen({ id: 'special_prompt', type: 'unfriend_user', target: user }))}>
|
||||||
<X size={24} />
|
<X size={24} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue