[NEW] Add an option to change message time format

This commit is contained in:
Danish Ahmed Mirza 2022-06-03 00:24:28 +05:30
parent 6220375f7b
commit 8b4cc16548
12 changed files with 94 additions and 10 deletions

View File

@ -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 }]}>

View File

@ -1077,6 +1077,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
username={user.username}
replying={replying}
getCustomEmoji={getCustomEmoji}
timeFormat={user.timeFormat}
/>
) : null;

View File

@ -21,6 +21,7 @@ export interface ILoggedUser {
showMessageInMainThread?: boolean;
isFromWebView?: boolean;
enableMessageParserEarlyAdoption: boolean;
timeFormat: number;
}
export interface ILoggedUserResultFromServer

View File

@ -112,6 +112,7 @@ export interface INotificationPreferences {
pushNotifications: TNotifications;
emailNotificationMode?: 'mentions' | 'nothing';
language?: string;
clockMode?: number;
}
export interface IUserPreferences {

View File

@ -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",

View File

@ -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;
}

View File

@ -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 }]
})
]
}
]
});

View File

@ -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({

View File

@ -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') {

View File

@ -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;
}

View File

@ -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;

View File

@ -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>
);