Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F32977530
D14810.1768315456.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D14810.1768315456.diff
View Options
diff --git a/lib/components/debug-logs-context-provider.react.js b/lib/components/debug-logs-context-provider.react.js
--- a/lib/components/debug-logs-context-provider.react.js
+++ b/lib/components/debug-logs-context-provider.react.js
@@ -5,6 +5,7 @@
import {
type DebugLog,
DebugLogsContext,
+ defaultLogsFilter,
type LogType,
} from './debug-logs-context.js';
import { useIsCurrentUserStaff } from '../shared/staff-utils.js';
@@ -16,6 +17,8 @@
function DebugLogsContextProvider(props: Props): React.Node {
const [logs, setLogs] = React.useState<$ReadOnlyArray<DebugLog>>([]);
+ const [logsFilter, setLogsFilter] =
+ React.useState<$ReadOnlySet<LogType>>(defaultLogsFilter);
const isCurrentUserStaff = useIsCurrentUserStaff();
const addLog = React.useCallback(
@@ -39,15 +42,45 @@
[isCurrentUserStaff],
);
- const clearLogs = React.useCallback(() => setLogs([]), []);
+ const isLogEnabled = React.useCallback(
+ (log: DebugLog) =>
+ [...log.logTypes].find(logType => logsFilter.has(logType)),
+ [logsFilter],
+ );
+
+ const clearLogs = React.useCallback(
+ () => setLogs(prev => prev.filter(log => !isLogEnabled(log))),
+ [isLogEnabled],
+ );
+
+ const filteredLogs = React.useMemo(
+ () => logs.filter(isLogEnabled),
+ [isLogEnabled, logs],
+ );
+
+ const setFilter = React.useCallback(
+ (logType: LogType, value: boolean) =>
+ setLogsFilter(prev => {
+ const newFilters = new Set(prev);
+ if (value) {
+ newFilters.add(logType);
+ } else {
+ newFilters.delete(logType);
+ }
+ return newFilters;
+ }),
+ [],
+ );
const contextValue = React.useMemo(
() => ({
- logs,
+ logsFilter,
+ logs: filteredLogs,
addLog,
clearLogs,
+ setFilter,
}),
- [addLog, clearLogs, logs],
+ [addLog, clearLogs, filteredLogs, logsFilter, setFilter],
);
return (
diff --git a/lib/components/debug-logs-context.js b/lib/components/debug-logs-context.js
--- a/lib/components/debug-logs-context.js
+++ b/lib/components/debug-logs-context.js
@@ -23,21 +23,27 @@
+logTypes: $ReadOnlySet<LogType>,
};
+const defaultLogsFilter: $ReadOnlySet<LogType> = new Set([logTypes.ERROR]);
+
export type DebugLogsContextType = {
+logs: $ReadOnlyArray<DebugLog>,
+ +logsFilter: $ReadOnlySet<LogType>,
+addLog: (
title: string,
message: string,
logTypes: $ReadOnlySet<LogType>,
) => mixed,
+clearLogs: () => mixed,
+ +setFilter: (logType: LogType, value: boolean) => mixed,
};
const DebugLogsContext: React.Context<DebugLogsContextType> =
React.createContext<DebugLogsContextType>({
+ logsFilter: defaultLogsFilter,
logs: [],
addLog: () => {},
clearLogs: () => {},
+ setFilter: () => {},
});
function useDebugLogs(): DebugLogsContextType {
@@ -140,4 +146,10 @@
);
}
-export { DebugLogsContext, useDebugLogs, useOlmDebugLogs, logTypes };
+export {
+ DebugLogsContext,
+ useDebugLogs,
+ useOlmDebugLogs,
+ logTypes,
+ defaultLogsFilter,
+};
diff --git a/native/profile/debug-logs-screen.react.js b/native/profile/debug-logs-screen.react.js
--- a/native/profile/debug-logs-screen.react.js
+++ b/native/profile/debug-logs-screen.react.js
@@ -2,12 +2,15 @@
import Clipboard from '@react-native-clipboard/clipboard';
import * as React from 'react';
-import { FlatList, View, Text } from 'react-native';
+import { FlatList, View, Text, Switch } from 'react-native';
import {
useDebugLogs,
type DebugLog,
+ logTypes,
+ type LogType,
} from 'lib/components/debug-logs-context.js';
+import { values } from 'lib/utils/objects.js';
import type { ProfileNavigationProp } from './profile.react.js';
import PrimaryButton from '../components/primary-button.react.js';
@@ -21,7 +24,7 @@
// eslint-disable-next-line no-unused-vars
function DebugLogsScreen(props: Props): React.Node {
- const { logs, clearLogs } = useDebugLogs();
+ const { logs, clearLogs, logsFilter, setFilter } = useDebugLogs();
const copyLogs = React.useCallback(() => {
Clipboard.setString(JSON.stringify(logs, null, 2));
@@ -44,11 +47,41 @@
[styles.item, styles.message, styles.timestamp, styles.title],
);
+ const toggleLogsFilter = React.useCallback(
+ (logType: LogType) => {
+ setFilter(logType, !logsFilter.has(logType));
+ },
+ [logsFilter, setFilter],
+ );
+
+ const logTypesList = React.useMemo(
+ () =>
+ values(logTypes).map(logType => (
+ <View style={styles.submenuButton} key={logType}>
+ <Text style={styles.submenuText}>{logType}</Text>
+ <Switch
+ value={!!logsFilter.has(logType)}
+ onValueChange={() => toggleLogsFilter(logType)}
+ />
+ </View>
+ )),
+ [logsFilter, styles.submenuButton, styles.submenuText, toggleLogsFilter],
+ );
+
return (
<View style={styles.view}>
+ {logTypesList}
<FlatList data={logs} renderItem={renderItem} />
- <PrimaryButton onPress={clearLogs} variant="danger" label="Clear logs" />
- <PrimaryButton onPress={copyLogs} variant="enabled" label="Copy logs" />
+ <PrimaryButton
+ onPress={clearLogs}
+ variant="danger"
+ label="Clear filtered logs"
+ />
+ <PrimaryButton
+ onPress={copyLogs}
+ variant="enabled"
+ label="Copy filtered logs"
+ />
</View>
);
}
@@ -77,6 +110,17 @@
message: {
color: 'panelForegroundSecondaryLabel',
},
+ submenuButton: {
+ flexDirection: 'row',
+ paddingHorizontal: 10,
+ paddingVertical: 2,
+ alignItems: 'center',
+ },
+ submenuText: {
+ color: 'panelForegroundLabel',
+ flex: 1,
+ fontSize: 16,
+ },
};
export default DebugLogsScreen;
diff --git a/web/settings/debug-logs-modal.react.js b/web/settings/debug-logs-modal.react.js
--- a/web/settings/debug-logs-modal.react.js
+++ b/web/settings/debug-logs-modal.react.js
@@ -2,15 +2,18 @@
import * as React from 'react';
-import { useDebugLogs } from 'lib/components/debug-logs-context.js';
+import { logTypes, useDebugLogs } from 'lib/components/debug-logs-context.js';
+import type { LogType } from 'lib/components/debug-logs-context.js';
import { useModalContext } from 'lib/components/modal-provider.react.js';
+import { values } from 'lib/utils/objects.js';
import css from './debug-logs-modal.css';
import Button, { buttonThemes } from '../components/button.react.js';
+import EnumSettingsOption from '../components/enum-settings-option.react.js';
import Modal from '../modals/modal.react.js';
function DebugLogsModal(): React.Node {
- const { logs, clearLogs } = useDebugLogs();
+ const { logs, clearLogs, logsFilter, setFilter } = useDebugLogs();
const { popModal } = useModalContext();
const messageList = React.useMemo(
@@ -33,13 +36,35 @@
await navigator.clipboard.writeText(JSON.stringify(logs, null, 2));
}, [logs]);
+ const toggleLogsFilter = React.useCallback(
+ (logType: LogType) => setFilter(logType, !logsFilter.has(logType)),
+ [logsFilter, setFilter],
+ );
+
+ const logTypesList = React.useMemo(
+ () =>
+ values(logTypes).map(logType => (
+ <EnumSettingsOption
+ key={logType}
+ selected={!!logsFilter.has(logType)}
+ onSelect={() => toggleLogsFilter(logType)}
+ icon={null}
+ title={logType}
+ type="checkbox"
+ statements={[{ statement: logType }]}
+ />
+ )),
+ [logsFilter, toggleLogsFilter],
+ );
+
return (
<Modal name="Debug Logs" onClose={popModal} size="large">
<div className={css.container}>
+ <div> {logTypesList}</div>
<div className={css.logsList}>{messageList}</div>
<div className={css.buttons}>
<Button variant="filled" className={css.button} onClick={copyLogs}>
- Copy logs
+ Copy filtered logs
</Button>
<Button
variant="filled"
@@ -47,7 +72,7 @@
className={css.button}
onClick={clearLogs}
>
- Clear logs
+ Clear filtered logs
</Button>
</div>
</div>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jan 13, 2:44 PM (3 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5927201
Default Alt Text
D14810.1768315456.diff (8 KB)
Attached To
Mode
D14810: [lib][web][native] implement log filtering
Attached
Detach File
Event Timeline
Log In to Comment