mirror of
https://github.com/wassname/talk.git
synced 2026-08-05 13:30:26 +08:00
[CORL-156] Manage user suspension status (#2419)
* wire up suspension modal * show user suspended callout on stream * prevent comment actions for suspended users * set default to 3 hour suspension * add message field to suspension * allow custom message for suspension * show suspend success modal * fix type errors * remove unused code * update styles * fix fixture for streams * add suspension ui tests * fix types * remove warnings? * remove snapshot * fix merge conflicts * allow custom email message when banning users * fix typo * correct message type * use final-form in suspend modal * refactor suspend modal to use final-form * refactor ban modal to use final-form * refactor userStatusChangeContainer to use useCallback * feat: improve translated form * fix: addressed issue caused by i18n refactor * update getMessage to accept arguments, remove format method * translate suspend info * change hour format * make message a mandatory input for suspend and ban user * fix types in user table * Revert "fix types in user table" This reverts commit d396e90b88bb1bd354c5cdbdd72b6d8f1ab72929. * fix types for user table * fix: small review tweaks
This commit is contained in:
committed by
Wyatt Johnson
parent
4e548e8fbf
commit
5df2de6afc
@@ -0,0 +1,18 @@
|
||||
import { FluentBundle } from "fluent/compat";
|
||||
|
||||
export default function format(
|
||||
bundles: FluentBundle[],
|
||||
key: string,
|
||||
args?: object
|
||||
): string {
|
||||
const res = bundles.reduce((val, bundle) => {
|
||||
const message = bundle.getMessage(key);
|
||||
const got = bundle.format(message, args);
|
||||
return val || got;
|
||||
}, "");
|
||||
if (res && Array.isArray(res)) {
|
||||
return res.join("");
|
||||
}
|
||||
|
||||
return res || "";
|
||||
}
|
||||
@@ -1,17 +1,21 @@
|
||||
import { FluentBundle } from "fluent/compat";
|
||||
|
||||
export default function getMessage(
|
||||
export default function getMessage<T extends {}>(
|
||||
bundles: FluentBundle[],
|
||||
key: string,
|
||||
defaultTo = ""
|
||||
defaultTo: string,
|
||||
args?: T
|
||||
): string {
|
||||
const res = bundles.reduce((val, bundle) => {
|
||||
const got = bundle.getMessage(key);
|
||||
if (!got && process.env.NODE_ENV !== "production") {
|
||||
const message = bundle.getMessage(key);
|
||||
if (!message && process.env.NODE_ENV !== "production") {
|
||||
// tslint:disable-next-line:no-console
|
||||
console.warn(`Translation ${key} was not found for ${bundle.locales}`);
|
||||
}
|
||||
return val || got;
|
||||
if (!args) {
|
||||
return val || message;
|
||||
}
|
||||
return val || bundle.format(message, args);
|
||||
}, "");
|
||||
if (res && Array.isArray(res)) {
|
||||
return res.join("");
|
||||
|
||||
@@ -3,3 +3,4 @@ export { default as negotiateLanguages } from "./negotiateLanguages";
|
||||
export { BundledLocales, LoadableLocales, LocalesData } from "./locales";
|
||||
export { default as getMessage } from "./getMessage";
|
||||
export { default as withGetMessage, GetMessage } from "./withGetMessage";
|
||||
export { default as reduceSeconds, UNIT, ScaledUnit } from "./reduceSeconds";
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* UNIT are units that can be used in the
|
||||
* DurationField components.
|
||||
*/
|
||||
export enum UNIT {
|
||||
SECONDS = 1,
|
||||
MINUTES = 60,
|
||||
HOURS = 3600,
|
||||
DAYS = 86400,
|
||||
WEEKS = 604800,
|
||||
}
|
||||
|
||||
export const UNIT_MAP = {
|
||||
[UNIT.SECONDS]: "second",
|
||||
[UNIT.MINUTES]: "minute",
|
||||
[UNIT.HOURS]: "hour",
|
||||
[UNIT.DAYS]: "day",
|
||||
[UNIT.WEEKS]: "week",
|
||||
};
|
||||
|
||||
export const DEFAULT_UNITS = [
|
||||
UNIT.WEEKS,
|
||||
UNIT.DAYS,
|
||||
UNIT.HOURS,
|
||||
UNIT.MINUTES,
|
||||
UNIT.SECONDS,
|
||||
];
|
||||
|
||||
type ValueOf<T> = T[keyof T];
|
||||
|
||||
export interface ScaledUnit {
|
||||
original: number;
|
||||
value: string;
|
||||
unit: ValueOf<typeof UNIT_MAP>;
|
||||
scaled: number;
|
||||
}
|
||||
|
||||
export default function reduceSeconds(
|
||||
value: number,
|
||||
units: UNIT[] = DEFAULT_UNITS
|
||||
): ScaledUnit {
|
||||
// Find the largest match for the smallest number.
|
||||
const unit: keyof typeof UNIT_MAP =
|
||||
units.find(compare => value >= compare) || UNIT.SECONDS;
|
||||
|
||||
// Scale the value to the unit.
|
||||
const scaled = Math.round((value / unit) * 100) / 100;
|
||||
|
||||
return {
|
||||
original: value,
|
||||
value: value.toString(),
|
||||
scaled,
|
||||
unit: UNIT_MAP[unit],
|
||||
};
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { DefaultingInferableComponentEnhancer, hoistStatics } from "recompose";
|
||||
import { CoralContext, withContext } from "../bootstrap";
|
||||
import getMessage from "./getMessage";
|
||||
|
||||
export type GetMessage = (id: string, defaultTo?: string) => string;
|
||||
export type GetMessage = <T>(id: string, defaultTo: string, args?: T) => string;
|
||||
|
||||
interface InjectedProps {
|
||||
getMessage: GetMessage;
|
||||
@@ -35,8 +35,12 @@ const withGetMessage: DefaultingInferableComponentEnhancer<
|
||||
const Workaround = BaseComponent as React.ComponentType<InjectedProps>;
|
||||
|
||||
class WithGetMessage extends React.Component<Props> {
|
||||
private getMessage = (id: string, defaultTo?: string) => {
|
||||
return getMessage(this.props.localeBundles, id, defaultTo);
|
||||
private getMessage = <U extends {}>(
|
||||
id: string,
|
||||
defaultTo: string,
|
||||
args?: U
|
||||
): string => {
|
||||
return getMessage(this.props.localeBundles, id, defaultTo, args);
|
||||
};
|
||||
public render() {
|
||||
const { localeBundles: _, ...rest } = this.props;
|
||||
|
||||
Reference in New Issue
Block a user