[NEW] Add an option to change message time format
This commit is contained in:
parent
6220375f7b
commit
8b4cc16548
|
@ -52,17 +52,25 @@ interface IMessageBoxReplyPreview {
|
|||
username: string;
|
||||
getCustomEmoji: Function;
|
||||
useRealName: boolean;
|
||||
timeFormat: number;
|
||||
}
|
||||
|
||||
const ReplyPreview = React.memo(
|
||||
({ message, Message_TimeFormat, replying, close, useRealName }: IMessageBoxReplyPreview) => {
|
||||
({ message, Message_TimeFormat, replying, close, useRealName, timeFormat }: IMessageBoxReplyPreview) => {
|
||||
const { theme } = useTheme();
|
||||
|
||||
const getTimeFormat = () => {
|
||||
const timeFormats = ['h:mm A', 'H:mm'];
|
||||
if (timeFormat) {
|
||||
return timeFormats[timeFormat - 1];
|
||||
}
|
||||
return Message_TimeFormat;
|
||||
};
|
||||
|
||||
if (!replying) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const time = moment(message.ts).format(Message_TimeFormat);
|
||||
const time = moment(message.ts).format(getTimeFormat());
|
||||
return (
|
||||
<View style={[styles.container, { backgroundColor: themes[theme].messageboxBackground }]}>
|
||||
<View style={[styles.messageContainer, { backgroundColor: themes[theme].chatComponentBackground }]}>
|
||||
|
|
|
@ -1077,6 +1077,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
|||
username={user.username}
|
||||
replying={replying}
|
||||
getCustomEmoji={getCustomEmoji}
|
||||
timeFormat={user.timeFormat}
|
||||
/>
|
||||
) : null;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ export interface ILoggedUser {
|
|||
showMessageInMainThread?: boolean;
|
||||
isFromWebView?: boolean;
|
||||
enableMessageParserEarlyAdoption: boolean;
|
||||
timeFormat: number;
|
||||
}
|
||||
|
||||
export interface ILoggedUserResultFromServer
|
||||
|
|
|
@ -112,6 +112,7 @@ export interface INotificationPreferences {
|
|||
pushNotifications: TNotifications;
|
||||
emailNotificationMode?: 'mentions' | 'nothing';
|
||||
language?: string;
|
||||
clockMode?: number;
|
||||
}
|
||||
|
||||
export interface IUserPreferences {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"1_person_reacted": "1 person reacted",
|
||||
"1_user": "1 user",
|
||||
"12_Hour": "12-hour clock",
|
||||
"24_Hour": "24-hour clock",
|
||||
"error-action-not-allowed": "{{action}} is not allowed",
|
||||
"error-application-not-found": "Application not found",
|
||||
"error-archived-duplicate-name": "There's an archived channel with name {{room_name}}",
|
||||
|
@ -327,6 +329,7 @@
|
|||
"Message": "Message",
|
||||
"Messages": "Messages",
|
||||
"Message_Reported": "Message reported",
|
||||
"Message_time_format": "Time format",
|
||||
"Microphone_Permission_Message": "Rocket.Chat needs access to your microphone so you can send audio message.",
|
||||
"Microphone_Permission": "Microphone Permission",
|
||||
"Mute": "Mute",
|
||||
|
|
|
@ -29,4 +29,6 @@ export default class User extends Model {
|
|||
@field('is_from_webview') isFromWebView;
|
||||
|
||||
@field('enable_message_parser_early_adoption') enableMessageParserEarlyAdoption;
|
||||
|
||||
@field('time_format') timeFormat;
|
||||
}
|
||||
|
|
|
@ -103,6 +103,15 @@ export default schemaMigrations({
|
|||
columns: [{ name: 'enable_message_parser_early_adoption', type: 'boolean', isOptional: true }]
|
||||
})
|
||||
]
|
||||
},
|
||||
{
|
||||
toVersion: 13,
|
||||
steps: [
|
||||
addColumns({
|
||||
table: 'users',
|
||||
columns: [{ name: 'time_format', type: 'number', isOptional: true }]
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { appSchema, tableSchema } from '@nozbe/watermelondb';
|
||||
|
||||
export default appSchema({
|
||||
version: 12,
|
||||
version: 13,
|
||||
tables: [
|
||||
tableSchema({
|
||||
name: 'users',
|
||||
|
@ -17,7 +17,8 @@ export default appSchema({
|
|||
{ name: 'show_message_in_main_thread', type: 'boolean', isOptional: true },
|
||||
{ name: 'avatar_etag', type: 'string', isOptional: true },
|
||||
{ name: 'is_from_webview', type: 'boolean', isOptional: true },
|
||||
{ name: 'enable_message_parser_early_adoption', type: 'boolean', isOptional: true }
|
||||
{ name: 'enable_message_parser_early_adoption', type: 'boolean', isOptional: true },
|
||||
{ name: 'time_format', type: 'number', isOptional: true }
|
||||
]
|
||||
}),
|
||||
tableSchema({
|
||||
|
|
|
@ -295,6 +295,9 @@ export default function subscribeRooms() {
|
|||
if ((['settings.preferences.showMessageInMainThread'] as any) in diff) {
|
||||
store.dispatch(setUser({ showMessageInMainThread: diff['settings.preferences.showMessageInMainThread'] }));
|
||||
}
|
||||
if ((['settings.preferences.clockMode'] as any) in diff) {
|
||||
store.dispatch(setUser({ timeFormat: diff['settings.preferences.clockMode'] }));
|
||||
}
|
||||
}
|
||||
if (/subscriptions/.test(ev)) {
|
||||
if (type === 'removed') {
|
||||
|
|
|
@ -285,7 +285,8 @@ async function login(credentials: ICredentials, isFromWebView = false): Promise<
|
|||
avatarETag: result.me.avatarETag,
|
||||
isFromWebView,
|
||||
showMessageInMainThread: result.me.settings?.preferences?.showMessageInMainThread ?? true,
|
||||
enableMessageParserEarlyAdoption: result.me.settings?.preferences?.enableMessageParserEarlyAdoption ?? true
|
||||
enableMessageParserEarlyAdoption: result.me.settings?.preferences?.enableMessageParserEarlyAdoption ?? true,
|
||||
timeFormat: result.me.settings?.preferences?.clockMode ?? 0
|
||||
};
|
||||
return user;
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ const roomAttrsUpdate = [
|
|||
] as TRoomUpdate[];
|
||||
|
||||
interface IRoomViewProps extends IBaseScreen<ChatsStackParamList, 'RoomView'> {
|
||||
user: Pick<ILoggedUser, 'id' | 'username' | 'token' | 'showMessageInMainThread'>;
|
||||
user: Pick<ILoggedUser, 'id' | 'username' | 'token' | 'showMessageInMainThread' | 'timeFormat'>;
|
||||
appState: string;
|
||||
useRealName?: boolean;
|
||||
isAuthenticated: boolean;
|
||||
|
@ -1183,10 +1183,19 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
|
|||
});
|
||||
};
|
||||
|
||||
getMessageTimeFormat = () => {
|
||||
const { user, Message_TimeFormat } = this.props;
|
||||
const timeFormats = ['h:mm A', 'H:mm'];
|
||||
if (user.timeFormat) {
|
||||
return timeFormats[user.timeFormat - 1];
|
||||
}
|
||||
return Message_TimeFormat;
|
||||
};
|
||||
|
||||
renderItem = (item: TAnyMessageModel, previousItem: TAnyMessageModel, highlightedMessage?: string) => {
|
||||
const { room, lastOpen, canAutoTranslate } = this.state;
|
||||
const { user, Message_GroupingPeriod, Message_TimeFormat, useRealName, baseUrl, Message_Read_Receipt_Enabled, theme } =
|
||||
this.props;
|
||||
const { user, Message_GroupingPeriod, useRealName, baseUrl, Message_Read_Receipt_Enabled, theme } = this.props;
|
||||
const Message_TimeFormat = this.getMessageTimeFormat();
|
||||
let dateSeparator = null;
|
||||
let showUnreadSeparator = false;
|
||||
|
||||
|
|
|
@ -14,14 +14,33 @@ import { getUserSelector } from '../../selectors/login';
|
|||
import { ProfileStackParamList } from '../../stacks/types';
|
||||
import { Services } from '../../lib/services';
|
||||
import { useAppSelector } from '../../lib/hooks';
|
||||
import { useTheme } from '../../theme';
|
||||
|
||||
interface IUserPreferencesViewProps {
|
||||
navigation: StackNavigationProp<ProfileStackParamList, 'UserPreferencesView'>;
|
||||
theme: string;
|
||||
}
|
||||
|
||||
const UserPreferencesView = ({ navigation }: IUserPreferencesViewProps): JSX.Element => {
|
||||
const { enableMessageParserEarlyAdoption, id } = useAppSelector(state => getUserSelector(state));
|
||||
const { enableMessageParserEarlyAdoption, timeFormat, id } = useAppSelector(state => getUserSelector(state));
|
||||
const dispatch = useDispatch();
|
||||
const { colors } = useTheme();
|
||||
|
||||
interface ITimeFormats {
|
||||
label: string;
|
||||
value: number;
|
||||
}
|
||||
|
||||
const timeFormats: ITimeFormats[] = [
|
||||
{
|
||||
label: '12_Hour',
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
label: '24_Hour',
|
||||
value: 2
|
||||
}
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
navigation.setOptions({
|
||||
|
@ -47,6 +66,17 @@ const UserPreferencesView = ({ navigation }: IUserPreferencesViewProps): JSX.Ele
|
|||
<Switch value={value} trackColor={SWITCH_TRACK_COLOR} onValueChange={toggleMessageParser} />
|
||||
);
|
||||
|
||||
const renderIcon = () => <List.Icon name='check' color={colors.tintColor} />;
|
||||
|
||||
const onChangeTimeFormat = async (item: ITimeFormats) => {
|
||||
try {
|
||||
dispatch(setUser({ timeFormat: item.value }));
|
||||
await Services.saveUserPreferences({ id, clockMode: item.value });
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView testID='preferences-view'>
|
||||
<StatusBar />
|
||||
|
@ -70,6 +100,21 @@ const UserPreferencesView = ({ navigation }: IUserPreferencesViewProps): JSX.Ele
|
|||
/>
|
||||
<List.Separator />
|
||||
</List.Section>
|
||||
<List.Section title='Message_time_format'>
|
||||
<List.Separator />
|
||||
<List.Item
|
||||
title={timeFormats[0].label}
|
||||
onPress={() => onChangeTimeFormat(timeFormats[0])}
|
||||
right={() => (timeFormat === timeFormats[0].value ? renderIcon() : null)}
|
||||
/>
|
||||
<List.Separator />
|
||||
<List.Item
|
||||
title={timeFormats[1].label}
|
||||
onPress={() => onChangeTimeFormat(timeFormats[1])}
|
||||
right={() => (timeFormat === timeFormats[1].value ? renderIcon() : null)}
|
||||
/>
|
||||
<List.Separator />
|
||||
</List.Section>
|
||||
</List.Container>
|
||||
</SafeAreaView>
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue