Skip to content

Commit 63a3e41

Browse files
fix
1 parent e06188d commit 63a3e41

5 files changed

Lines changed: 131 additions & 33 deletions

File tree

packages/viewer/src/components/Dev/Explore.svelte

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,10 @@
11
<script lang="ts">
22
import context from '@/context'
33
import Log from './Log.svelte'
4-
import { defaultStorage } from '@/repositories'
54
import { reset } from '@/util'
5+
import { showLeanLinks, showRedundancy } from '@/stores/settings'
66
77
const { spaces, properties, theorems, traits } = context()
8-
9-
let showRedundancy = defaultStorage.getItem('showRedundancy') !== null
10-
$: showRedundancy
11-
? defaultStorage.setItem('showRedundancy', 'show')
12-
: defaultStorage.removeItem('showRedundancy')
13-
14-
let showLeanLinks = defaultStorage.getItem('showLeanLinks') !== null
15-
$: showLeanLinks
16-
? defaultStorage.setItem('showLeanLinks', 'show')
17-
: defaultStorage.removeItem('showLeanLinks')
188
</script>
199

2010
<h4>Entities</h4>
@@ -52,7 +42,7 @@
5242
<input
5343
id="redundancyCheckbox"
5444
type="checkbox"
55-
bind:checked={showRedundancy}
45+
bind:checked={$showRedundancy}
5646
/>
5747
<label for="redundancyCheckbox"> Show redundancies in tables </label>
5848
</td>
@@ -62,7 +52,7 @@
6252
<input
6353
id="leanLinksCheckbox"
6454
type="checkbox"
65-
bind:checked={showLeanLinks}
55+
bind:checked={$showLeanLinks}
6656
/>
6757
<label for="leanLinksCheckbox">
6858
Show Lean formalisation links (experimental)

packages/viewer/src/components/Shared/LeanLink.svelte

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
<script context="module" lang="ts">
22
const repo = 'felixpernegger/pibase-lean'
33
4-
const directories: Record<string, Promise<Set<string>>> = {
5-
property: fetchDirectory('PiBaseLean/Properties'),
6-
theorem: fetchDirectory('PiBaseLean/Theorems'),
4+
const cache: Record<string, Promise<Set<string>>> = {}
5+
6+
function getDirectory(kind: 'property' | 'theorem'): Promise<Set<string>> {
7+
const path =
8+
kind === 'property' ? 'PiBaseLean/Properties' : 'PiBaseLean/Theorems'
9+
if (!cache[kind]) {
10+
cache[kind] = fetchDirectory(path)
11+
}
12+
return cache[kind]
713
}
814
915
async function fetchDirectory(path: string): Promise<Set<string>> {
@@ -21,14 +27,12 @@
2127
</script>
2228

2329
<script lang="ts">
24-
import { onMount } from 'svelte'
2530
import { Icons } from '@/components/Shared'
26-
import { defaultStorage } from '@/repositories'
31+
import { showLeanLinks } from '@/stores/settings'
2732
2833
export let kind: 'property' | 'theorem'
2934
export let id: number
3035
31-
let enabled = defaultStorage.getItem('showLeanLinks') !== null
3236
let loaded = false
3337
let available = false
3438
@@ -38,18 +42,15 @@
3842
kind === 'property' ? 'PiBaseLean/Properties' : 'PiBaseLean/Theorems'
3943
$: href = `https://github.com/${repo}/blob/master/${basePath}/${folderName}/${file}`
4044
41-
onMount(async () => {
42-
if (!enabled) {
45+
$: if ($showLeanLinks && !loaded) {
46+
getDirectory(kind).then(ids => {
47+
available = ids.has(folderName)
4348
loaded = true
44-
return
45-
}
46-
const ids = await directories[kind]
47-
available = ids.has(folderName)
48-
loaded = true
49-
})
49+
})
50+
}
5051
</script>
5152

52-
{#if enabled && loaded}
53+
{#if $showLeanLinks && loaded}
5354
{#if available}
5455
<div>
5556
<a {href} target="_blank" rel="noopener noreferrer">

packages/viewer/src/components/Traits/Related.svelte

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
import context from '@/context'
66
import type { Property, Space, Trait, Traits } from '@/models'
77
import FilterButtons from './FilterButtons.svelte'
8-
import { defaultStorage } from '@/repositories'
98
import { writable } from 'svelte/store'
9+
import { showRedundancy } from '@/stores/settings'
1010
import urlSearchParam from '@/stores/urlSearchParam'
1111
import { checkIfRedundant } from '@/stores/deduction'
1212
@@ -21,8 +21,6 @@
2121
let filterMode: 'all' | 'known' | 'asserted' | 'true' | 'false' | 'missing'
2222
filterMode = 'known'
2323
24-
let showRedundancy = defaultStorage.getItem('showRedundancy') != null
25-
2624
$: all = related($traits)
2725
// all has type [Space, Property, Trait][]
2826
// we need to index names in different positions depending on which kind we
@@ -109,10 +107,9 @@
109107
<Link.Trait {space} {property}>
110108
<SourceIcon
111109
value={trait?.asserted}
112-
redundant={showRedundancy &&
110+
redundant={$showRedundancy &&
113111
trait?.asserted &&
114112
checkIfRedundant(space, property, $theorems, $traits).redundant}
115-
icon="user"
116113
/>
117114
</Link.Trait>
118115
</td>
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { beforeEach, describe, expect, it } from 'vitest'
2+
import { get } from 'svelte/store'
3+
import { persistedBoolean, showLeanLinks, showRedundancy } from './settings'
4+
5+
function mockStorage() {
6+
const data: Record<string, string> = {}
7+
return {
8+
data,
9+
getItem: (key: string) => data[key] ?? null,
10+
setItem: (key: string, value: string) => {
11+
data[key] = value
12+
},
13+
removeItem: (key: string) => {
14+
delete data[key]
15+
},
16+
}
17+
}
18+
19+
describe('persistedBoolean', () => {
20+
it('defaults to the given default value when storage is empty', () => {
21+
const storage = mockStorage()
22+
const store = persistedBoolean('flag', false, storage)
23+
expect(get(store)).toBe(false)
24+
})
25+
26+
it('initializes to true when the key already exists in storage', () => {
27+
const storage = mockStorage()
28+
storage.data['flag'] = 'show'
29+
const store = persistedBoolean('flag', false, storage)
30+
expect(get(store)).toBe(true)
31+
})
32+
33+
it('writes to storage when set to true', () => {
34+
const storage = mockStorage()
35+
const store = persistedBoolean('flag', false, storage)
36+
store.set(true)
37+
expect(storage.data['flag']).toBe('show')
38+
})
39+
40+
it('removes from storage when set to false', () => {
41+
const storage = mockStorage()
42+
storage.data['flag'] = 'show'
43+
const store = persistedBoolean('flag', true, storage)
44+
store.set(false)
45+
expect(storage.data['flag']).toBeUndefined()
46+
})
47+
48+
it('reflects updates via subscribe', () => {
49+
const storage = mockStorage()
50+
const store = persistedBoolean('flag', false, storage)
51+
const values: boolean[] = []
52+
store.subscribe(v => values.push(v))
53+
54+
store.set(true)
55+
store.set(false)
56+
57+
expect(values).toEqual([false, true, false])
58+
})
59+
})
60+
61+
describe('showLeanLinks', () => {
62+
it('defaults to false', () => {
63+
expect(get(showLeanLinks)).toBe(false)
64+
})
65+
66+
it('can be toggled', () => {
67+
showLeanLinks.set(true)
68+
expect(get(showLeanLinks)).toBe(true)
69+
showLeanLinks.set(false)
70+
expect(get(showLeanLinks)).toBe(false)
71+
})
72+
})
73+
74+
describe('showRedundancy', () => {
75+
it('defaults to false', () => {
76+
expect(get(showRedundancy)).toBe(false)
77+
})
78+
79+
it('can be toggled', () => {
80+
showRedundancy.set(true)
81+
expect(get(showRedundancy)).toBe(true)
82+
showRedundancy.set(false)
83+
expect(get(showRedundancy)).toBe(false)
84+
})
85+
})
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { writable } from 'svelte/store'
2+
import { defaultStorage } from '@/repositories'
3+
4+
export function persistedBoolean(
5+
key: string,
6+
defaultValue: boolean,
7+
storage: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'> = defaultStorage,
8+
) {
9+
const store = writable<boolean>(
10+
storage.getItem(key) !== null ? true : defaultValue,
11+
)
12+
13+
store.subscribe(v => {
14+
if (v) {
15+
storage.setItem(key, 'show')
16+
} else {
17+
storage.removeItem(key)
18+
}
19+
})
20+
21+
return store
22+
}
23+
24+
export const showLeanLinks = persistedBoolean('showLeanLinks', false)
25+
export const showRedundancy = persistedBoolean('showRedundancy', false)

0 commit comments

Comments
 (0)