@@ -13,7 +13,7 @@ import * as Notifications from "../elements/notifications";
1313import * as ImportExportSettingsModal from "../modals/import-export-settings" ;
1414import * as ConfigEvent from "../observables/config-event" ;
1515import * as ActivePage from "../states/active-page" ;
16- import Page from "./page" ;
16+ import { PageWithUrlParams } from "./page" ;
1717import { isAuthenticated } from "../firebase" ;
1818import { get as getTypingSpeedUnit } from "../utils/typing-speed-units" ;
1919import SlimSelect from "slim-select" ;
@@ -25,6 +25,7 @@ import {
2525 ThemeName ,
2626 CustomLayoutFluid ,
2727 FunboxName ,
28+ ConfigKeySchema ,
2829} from "@monkeytype/contracts/schemas/configs" ;
2930import { getAllFunboxes , checkCompatibility } from "@monkeytype/funbox" ;
3031import { getActiveFunboxNames } from "../test/funbox/list" ;
@@ -37,6 +38,7 @@ import { areSortedArraysEqual, areUnsortedArraysEqual } from "../utils/arrays";
3738import { LayoutName } from "@monkeytype/contracts/schemas/layouts" ;
3839import { LanguageGroupNames , LanguageGroups } from "../constants/languages" ;
3940import { Language } from "@monkeytype/contracts/schemas/languages" ;
41+ import { z } from "zod" ;
4042
4143let settingsInitialized = false ;
4244
@@ -46,6 +48,24 @@ let customPolyglotSelect: SlimSelect | undefined;
4648
4749export const groups : SettingsGroups < ConfigValue > = { } ;
4850
51+ const HighlightSchema = ConfigKeySchema . or (
52+ z . enum ( [
53+ "resetSettings" ,
54+ "updateCookiePreferences" ,
55+ "importexportSettings" ,
56+ "theme" ,
57+ "presets" ,
58+ "tags" ,
59+ ] )
60+ ) ;
61+ type Highlight = z . infer < typeof HighlightSchema > ;
62+
63+ const StateSchema = z
64+ . object ( {
65+ highlight : HighlightSchema ,
66+ } )
67+ . partial ( ) ;
68+
4969async function initGroups ( ) : Promise < void > {
5070 groups [ "smoothCaret" ] = new SettingsGroup (
5171 "smoothCaret" ,
@@ -1001,7 +1021,7 @@ $(".pageSettings .section[data-config-name='minBurst']").on(
10011021) ;
10021022
10031023//funbox
1004- $ ( ".pageSettings .section[data-config-name='funbox']" ) . on (
1024+ $ ( ".pageSettings .section[data-config-name='funbox'] .buttons " ) . on (
10051025 "click" ,
10061026 "button" ,
10071027 ( e ) => {
@@ -1333,6 +1353,40 @@ function getThemeDropdownData(
13331353 } ) ) ;
13341354}
13351355
1356+ function handleHighlightSection ( highlight : Highlight ) : void {
1357+ const element = document . querySelector (
1358+ `[data-config-name="${ highlight } "] .groupTitle,[data-section-id="${ highlight } "] .groupTitle`
1359+ ) ;
1360+
1361+ if ( element !== null ) {
1362+ setTimeout ( ( ) => {
1363+ element . scrollIntoView ( { block : "center" , behavior : "auto" } ) ;
1364+ element . parentElement ?. classList . remove ( "highlight" ) ;
1365+ element . parentElement ?. classList . add ( "highlight" ) ;
1366+ } , 250 ) ;
1367+ }
1368+ }
1369+
1370+ $ ( ".pageSettings .section .groupTitle button" ) . on ( "click" , ( e ) => {
1371+ const section = e . target . parentElement ?. parentElement ;
1372+ const configName = ( section ?. dataset ?. [ "configName" ] ??
1373+ section ?. dataset ?. [ "sectionId" ] ) as Highlight | undefined ;
1374+ if ( configName === undefined ) {
1375+ return ;
1376+ }
1377+
1378+ page . setUrlParams ( { highlight : configName } ) ;
1379+
1380+ navigator . clipboard
1381+ . writeText ( window . location . toString ( ) )
1382+ . then ( ( ) => {
1383+ Notifications . add ( "Link copied to clipboard" , 1 ) ;
1384+ } )
1385+ . catch ( ( e : unknown ) => {
1386+ Notifications . add ( "Failed to copy to clipboard: " + e , - 1 ) ;
1387+ } ) ;
1388+ } ) ;
1389+
13361390ConfigEvent . subscribe ( ( eventKey , eventValue ) => {
13371391 if ( eventKey === "fullConfigChange" ) setEventDisabled ( true ) ;
13381392 if ( eventKey === "fullConfigChangeFinished" ) setEventDisabled ( false ) ;
@@ -1352,18 +1406,22 @@ ConfigEvent.subscribe((eventKey, eventValue) => {
13521406 }
13531407} ) ;
13541408
1355- export const page = new Page ( {
1409+ export const page = new PageWithUrlParams ( {
13561410 id : "settings" ,
13571411 element : $ ( ".page.pageSettings" ) ,
13581412 path : "/settings" ,
1413+ urlParamsSchema : StateSchema ,
13591414 afterHide : async ( ) : Promise < void > => {
13601415 Skeleton . remove ( "pageSettings" ) ;
13611416 } ,
1362- beforeShow : async ( ) : Promise < void > => {
1417+ beforeShow : async ( options ) : Promise < void > => {
13631418 Skeleton . append ( "pageSettings" , "main" ) ;
13641419 await UpdateConfig . loadPromise ;
13651420 await fillSettingsPage ( ) ;
13661421 await update ( ) ;
1422+ if ( options . urlParams ?. highlight !== undefined ) {
1423+ handleHighlightSection ( options . urlParams . highlight ) ;
1424+ }
13671425 } ,
13681426} ) ;
13691427
0 commit comments