diff --git a/services/web/app/src/Features/Project/ProjectController.js b/services/web/app/src/Features/Project/ProjectController.js index c8f88c18d9..7bf8db6cc8 100644 --- a/services/web/app/src/Features/Project/ProjectController.js +++ b/services/web/app/src/Features/Project/ProjectController.js @@ -792,6 +792,7 @@ const _ProjectController = { lineHeight: user.ace.lineHeight || 'normal', overallTheme: user.ace.overallTheme, mathPreview: user.ace.mathPreview, + referencesSearchMode: user.ace.referencesSearchMode, }, privilegeLevel, anonymous, diff --git a/services/web/app/src/Features/User/UserController.js b/services/web/app/src/Features/User/UserController.js index a4d886915a..404437d758 100644 --- a/services/web/app/src/Features/User/UserController.js +++ b/services/web/app/src/Features/User/UserController.js @@ -386,6 +386,11 @@ async function updateUserSettings(req, res, next) { if (req.body.mathPreview != null) { user.ace.mathPreview = req.body.mathPreview } + if (req.body.referencesSearchMode != null) { + const mode = + req.body.referencesSearchMode === 'simple' ? 'simple' : 'advanced' + user.ace.referencesSearchMode = mode + } await user.save() const newEmail = req.body.email?.trim().toLowerCase() diff --git a/services/web/app/src/models/User.js b/services/web/app/src/models/User.js index 2d1b23929f..c3bca59add 100644 --- a/services/web/app/src/models/User.js +++ b/services/web/app/src/models/User.js @@ -97,6 +97,7 @@ const UserSchema = new Schema( fontFamily: { type: String }, lineHeight: { type: String }, mathPreview: { type: Boolean, default: true }, + referencesSearchMode: { type: String, default: 'advanced' }, // 'advanced' or 'simple' }, features: { collaborators: { diff --git a/services/web/frontend/js/features/source-editor/extensions/index.ts b/services/web/frontend/js/features/source-editor/extensions/index.ts index 63d8db3f74..cd75b21b9a 100644 --- a/services/web/frontend/js/features/source-editor/extensions/index.ts +++ b/services/web/frontend/js/features/source-editor/extensions/index.ts @@ -115,6 +115,7 @@ export const createExtensions = (options: Record): Extension[] => [ autoComplete({ enabled: options.settings.autoComplete, projectFeatures: options.projectFeatures, + referencesSearchMode: options.settings.referencesSearchMode, }), // NOTE: `keybindings` needs to be before `language` so that Vim/Emacs bindings take diff --git a/services/web/frontend/js/features/source-editor/hooks/use-codemirror-scope.ts b/services/web/frontend/js/features/source-editor/hooks/use-codemirror-scope.ts index c4a1090431..4c9d510aff 100644 --- a/services/web/frontend/js/features/source-editor/hooks/use-codemirror-scope.ts +++ b/services/web/frontend/js/features/source-editor/hooks/use-codemirror-scope.ts @@ -96,6 +96,7 @@ function useCodeMirrorScope(view: EditorView) { mode, syntaxValidation, mathPreview, + referencesSearchMode, } = userSettings const [cursorHighlights] = useScopeValue>( @@ -169,6 +170,7 @@ function useCodeMirrorScope(view: EditorView) { mode, syntaxValidation, mathPreview, + referencesSearchMode, }) const currentDocRef = useRef({ @@ -430,6 +432,7 @@ function useCodeMirrorScope(view: EditorView) { setAutoComplete({ enabled: autoComplete, projectFeatures: projectFeaturesRef.current, + referencesSearchMode: settingsRef.current.referencesSearchMode, }) ) }) @@ -458,6 +461,10 @@ function useCodeMirrorScope(view: EditorView) { }) }, [view, mathPreview]) + useEffect(() => { + settingsRef.current.referencesSearchMode = referencesSearchMode + }, [referencesSearchMode]) + const emitSyncToPdf = useScopeEventEmitter('cursor:editor:syncToPdf') const handleGoToLine = useCallback( diff --git a/services/web/frontend/js/shared/context/user-settings-context.tsx b/services/web/frontend/js/shared/context/user-settings-context.tsx index 200f753c0e..67c9e437a1 100644 --- a/services/web/frontend/js/shared/context/user-settings-context.tsx +++ b/services/web/frontend/js/shared/context/user-settings-context.tsx @@ -25,6 +25,7 @@ const defaultSettings: UserSettings = { fontFamily: 'monaco', lineHeight: 'normal', mathPreview: true, + referencesSearchMode: 'advanced', } type UserSettingsContextValue = { diff --git a/services/web/test/unit/src/User/UserControllerTests.js b/services/web/test/unit/src/User/UserControllerTests.js index 160e877ad2..98ae8db73e 100644 --- a/services/web/test/unit/src/User/UserControllerTests.js +++ b/services/web/test/unit/src/User/UserControllerTests.js @@ -425,6 +425,33 @@ describe('UserController', function () { this.UserController.updateUserSettings(this.req, this.res) }) + it('should set referencesSearchMode to advanced', function (done) { + this.req.body = { referencesSearchMode: 'advanced' } + this.res.sendStatus = code => { + this.user.ace.referencesSearchMode.should.equal('advanced') + done() + } + this.UserController.updateUserSettings(this.req, this.res) + }) + + it('should set referencesSearchMode to simple', function (done) { + this.req.body = { referencesSearchMode: 'simple' } + this.res.sendStatus = code => { + this.user.ace.referencesSearchMode.should.equal('simple') + done() + } + this.UserController.updateUserSettings(this.req, this.res) + }) + + it('should not allow arbitrary referencesSearchMode', function (done) { + this.req.body = { referencesSearchMode: 'foobar' } + this.res.sendStatus = code => { + this.user.ace.referencesSearchMode.should.equal('advanced') + done() + } + this.UserController.updateUserSettings(this.req, this.res) + }) + it('should send an error if the email is 0 len', function (done) { this.req.body.email = '' this.res.sendStatus = function (code) { diff --git a/services/web/types/user-settings.ts b/services/web/types/user-settings.ts index 0f49d11dad..2753e09777 100644 --- a/services/web/types/user-settings.ts +++ b/services/web/types/user-settings.ts @@ -15,4 +15,5 @@ export type UserSettings = { fontFamily: FontFamily lineHeight: LineHeight mathPreview: boolean + referencesSearchMode: 'advanced' | 'simple' }