forked from WorldBrain/Memex
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.ts
107 lines (92 loc) · 3.08 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { browser } from 'webextension-polyfill-ts'
import { remoteFunction } from 'src/util/webextensionRPC'
import { RetryTimeoutError } from 'src/direct-linking/utils'
import { getLocalStorage, setLocalStorage } from 'src/util/storage'
import * as constants from './constants'
/**
* Keeps executing a promiseCreator function till no error is thrown.
*/
export function retryUntilErrorResolves(
promiseCreator,
{
intervalMilliSeconds,
timeoutMilliSeconds,
}: { intervalMilliSeconds: number; timeoutMilliSeconds: number },
) {
const startMs = Date.now()
return new Promise((resolve, reject) => {
const doTry = async () => {
let res
try {
res = await promiseCreator()
resolve(res)
return true
} catch (e) {
return false
}
}
const tryOrRetryLater = async () => {
if (await doTry()) {
resolve(true)
return
}
if (Date.now() - startMs >= timeoutMilliSeconds) {
return reject(new RetryTimeoutError())
}
setTimeout(tryOrRetryLater, intervalMilliSeconds)
}
tryOrRetryLater()
})
}
/**
* Calculates the number of pixels from the starting of the webpage.
* @param {HTMLElement} element DOM element to calculate the offsetTop.
* @returns The number of pixels from the starting of the webpage.
*/
export const getOffsetTop = (element: HTMLElement) => {
let el = element
let offset = 0
while (el) {
offset = offset + el.offsetTop
el = el.offsetParent as HTMLElement
}
return offset
}
export const getSidebarState = async () =>
getLocalStorage(
constants.SIDEBAR_STORAGE_NAME,
constants.SIDEBAR_DEFAULT_OPTION,
)
export const setSidebarState = async (enabled: boolean) =>
setLocalStorage(constants.SIDEBAR_STORAGE_NAME, enabled)
export const getExtUrl = (location: string) =>
browser.runtime ? browser.runtime.getURL(location) : location
// TODO: Perhaps move RPC calls to some sort of a manager.
const openOptionsTabRPC = remoteFunction('openOptionsTab')
export const openSettings = () => openOptionsTabRPC('settings')
// Compute the maximum width of a Tag pill
const avgLetterPx = 8
// Padding + Margin + X button
const tagPillExtra = 10 + 8 + 12
const tagContainerWidth = 240
const computeTagPillWidth = (letters: number) =>
letters * avgLetterPx + tagPillExtra
/**
* Given a list of tags, computes the maximum possible number of tags the
* container can hold without overflowing.
* @param {Array<String>} tags Array of tag names
* @returns {Number} Maximum possible tags the container can hold.
*/
export const maxPossibleTags = (tags: string[]) => {
let totalTagsWidth = 0
let tagsAllowed = 0
while (tagsAllowed < tags.length) {
const tag = tags[tagsAllowed]
totalTagsWidth += computeTagPillWidth(tag.length)
if (totalTagsWidth >= tagContainerWidth) {
break
}
tagsAllowed++
}
return tagsAllowed
}