mirror of
https://github.com/insin/control-panel-for-twitter.git
synced 2025-06-18 14:45:31 -04:00
Compare commits
2 Commits
c401ecb219
...
bfd15c51cd
Author | SHA1 | Date | |
---|---|---|---|
![]() |
bfd15c51cd | ||
![]() |
f80d24c74b |
153
script.js
153
script.js
@ -1913,6 +1913,14 @@ const THEME_COLORS = new Map([
|
||||
['orange500', 'rgb(255, 122, 0)'],
|
||||
['green500', 'rgb(0, 186, 124)'],
|
||||
])
|
||||
const THEME_COLOR_HOVERS = new Map([
|
||||
['blue500', 'rgb(26, 140, 216)'],
|
||||
['yellow500', 'rgb(230, 191, 0)'],
|
||||
['magenta500', 'rgb(224, 22, 115)'],
|
||||
['purple500', 'rgb(108, 77, 230)'],
|
||||
['orange500', 'rgb(230, 110, 0)'],
|
||||
['green500', 'rgb(0, 167, 122)'],
|
||||
])
|
||||
const THEME_COLOR_ACCENTS = new Map([
|
||||
['blue500', 'rgb(142, 205, 248)'],
|
||||
['yellow500', 'rgb(255, 234, 128)'],
|
||||
@ -1937,6 +1945,14 @@ const HIGH_CONTRAST_LIGHT_ACCENTS = new Map([
|
||||
['orange500', 'rgb(196, 149, 128)'],
|
||||
['green500', 'rgb(128, 176, 158)'],
|
||||
])
|
||||
const HIGH_CONTRAST_LIGHT_HOVERS = new Map([
|
||||
['blue500', 'rgb(26, 76, 146)'],
|
||||
['yellow500', 'rgb(125, 81, 26)'],
|
||||
['magenta500', 'rgb(149, 35, 89)'],
|
||||
['purple500', 'rgb(99, 72, 190)'],
|
||||
['orange500', 'rgb(149, 64, 26)'],
|
||||
['green500', 'rgb(26, 113, 80)'],
|
||||
])
|
||||
const HIGH_CONTRAST_DARK = new Map([
|
||||
['blue500', 'rgb(107, 201, 251)'],
|
||||
['yellow500', 'rgb(255, 235, 107)'],
|
||||
@ -1953,6 +1969,14 @@ const HIGH_CONTRAST_DARK_ACCENTS = new Map([
|
||||
['orange500', 'rgb(255, 214, 176)'],
|
||||
['green500', 'rgb(176, 235, 209)'],
|
||||
])
|
||||
const HIGH_CONTRAST_DARK_HOVERS = new Map([
|
||||
['blue500', 'rgb(96, 181, 226)'],
|
||||
['yellow500', 'rgb(230, 212, 96)'],
|
||||
['magenta500', 'rgb(226, 101, 158)'],
|
||||
['purple500', 'rgb(155, 136, 230)'],
|
||||
['orange500', 'rgb(230, 156, 87)'],
|
||||
['green500', 'rgb(87, 193, 147)'],
|
||||
])
|
||||
const COMPOSE_TWEET_MODAL_PAGES = new Set([
|
||||
ModalPaths.COMPOSE_DRAFTS,
|
||||
ModalPaths.COMPOSE_MEDIA,
|
||||
@ -2086,6 +2110,12 @@ let nativeThemeColor = THEME_COLORS.get('blue500')
|
||||
*/
|
||||
let nativeThemeColorAccent = THEME_COLOR_ACCENTS.get('blue500')
|
||||
|
||||
/**
|
||||
* Hover for the current "Color" setting.
|
||||
* @type {string}
|
||||
*/
|
||||
let nativeThemeColorHover = THEME_COLOR_HOVERS.get('blue500')
|
||||
|
||||
/**
|
||||
* `true` after the app has initialised.
|
||||
* @type {boolean}
|
||||
@ -2516,12 +2546,14 @@ function getThemeColorFromState() {
|
||||
if (THEME_COLORS.has(color)) {
|
||||
let colors = THEME_COLORS
|
||||
let accents = THEME_COLOR_ACCENTS
|
||||
let hovers = THEME_COLOR_HOVERS
|
||||
if (highContrast) {
|
||||
let colorScheme = getColorScheme()
|
||||
colors = colorScheme == 'Default' ? HIGH_CONTRAST_LIGHT : HIGH_CONTRAST_DARK
|
||||
accents = colorScheme == 'Default' ? HIGH_CONTRAST_LIGHT_ACCENTS : HIGH_CONTRAST_DARK_ACCENTS
|
||||
hovers = colorScheme == 'Default' ? HIGH_CONTRAST_LIGHT_HOVERS : HIGH_CONTRAST_DARK_HOVERS
|
||||
}
|
||||
return [colors.get(color), accents.get(color)]
|
||||
return [colors.get(color), accents.get(color), hovers.get(color)]
|
||||
}
|
||||
warn(color, 'not found in THEME_COLORS')
|
||||
} else {
|
||||
@ -2971,6 +3003,60 @@ async function observeTitle() {
|
||||
observers: globalObservers,
|
||||
})
|
||||
}
|
||||
|
||||
function observeReactNativeStylesheet() {
|
||||
let $style = /** @type {HTMLStyleElement} */ (document.querySelector('style#react-native-stylesheet'))
|
||||
if (!$style) {
|
||||
warn('React Native stylesheet not found')
|
||||
return
|
||||
}
|
||||
|
||||
let insertRule = $style.sheet.insertRule
|
||||
let timeout
|
||||
let cleanup = {
|
||||
name: 'React Native stylesheet (for rules being added)',
|
||||
disconnect() {
|
||||
clearTimeout(timeout)
|
||||
$style.sheet.insertRule = insertRule
|
||||
globalObservers.delete(cleanup.name)
|
||||
log(`disconnected ${cleanup.name} observer`)
|
||||
}
|
||||
}
|
||||
globalObservers.get(cleanup.name)?.disconnect()
|
||||
globalObservers.set(cleanup.name, cleanup)
|
||||
|
||||
// @ts-ignore
|
||||
$style.sheet.insertRule = function(...args) {
|
||||
clearTimeout(timeout)
|
||||
timeout = setTimeout(checkRules, 100)
|
||||
insertRule.apply(this, args)
|
||||
}
|
||||
|
||||
function checkRules() {
|
||||
for (let rule of $style.sheet.cssRules) {
|
||||
if (!(rule instanceof CSSStyleRule)) continue
|
||||
|
||||
if (fontFamilyRule == null &&
|
||||
rule.style.fontFamily?.includes('TwitterChirp') &&
|
||||
!rule.style.fontFamily.includes('TwitterChirpExtendedHeavy')) {
|
||||
fontFamilyRule = rule
|
||||
log('found Chirp fontFamily CSS rule in React Native stylesheet', fontFamilyRule)
|
||||
configureFont()
|
||||
}
|
||||
|
||||
if (filterBlurRule == null && rule.style.filter?.includes('blur(30px)')) {
|
||||
filterBlurRule = rule
|
||||
log('found filter: blur(30px) rule in React Native stylesheet', filterBlurRule)
|
||||
configureDynamicCss()
|
||||
}
|
||||
}
|
||||
if (fontFamilyRule != null && filterBlurRule != null) {
|
||||
cleanup.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
checkRules()
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region Page observers
|
||||
@ -4373,6 +4459,8 @@ const configureThemeCss = (() => {
|
||||
cssRules.push(`
|
||||
body {
|
||||
--theme-color: ${themeColor};
|
||||
--theme-color-accent: ${nativeThemeColorAccent};
|
||||
--theme-color-hover: ${nativeThemeColorHover};
|
||||
}
|
||||
`)
|
||||
|
||||
@ -4431,7 +4519,7 @@ const configureThemeCss = (() => {
|
||||
[data-testid="SideNav_NewTweet_Button"]:hover,
|
||||
[data-testid="tweetButtonInline"]:hover:not(:disabled),
|
||||
[data-testid="tweetButton"]:hover:not(:disabled) {
|
||||
background-color: rgb(from var(--theme-color) r g b / 0.8) !important;
|
||||
background-color: var(--theme-color-hover) !important;
|
||||
}
|
||||
body:is(.Dim, .LightsOut):not(.HighContrast) [data-testid="SideNav_NewTweet_Button"] > div,
|
||||
body:is(.Dim, .LightsOut):not(.HighContrast) [data-testid="tweetButtonInline"] > div,
|
||||
@ -4722,53 +4810,6 @@ function checkForDisabledHomeTimeline() {
|
||||
}
|
||||
}
|
||||
|
||||
function checkReactNativeStylesheet() {
|
||||
let $style = /** @type {HTMLStyleElement} */ (document.querySelector('style#react-native-stylesheet'))
|
||||
if (!$style) {
|
||||
warn('React Native stylesheet not found')
|
||||
return
|
||||
}
|
||||
|
||||
let lastRulesCount = null
|
||||
let startTime = Date.now()
|
||||
|
||||
function findRules() {
|
||||
for (let rule of $style.sheet.cssRules) {
|
||||
if (!(rule instanceof CSSStyleRule)) continue
|
||||
|
||||
if (fontFamilyRule == null &&
|
||||
rule.style.fontFamily?.includes('TwitterChirp') &&
|
||||
!rule.style.fontFamily.includes('TwitterChirpExtendedHeavy')) {
|
||||
fontFamilyRule = rule
|
||||
log('found Chirp fontFamily CSS rule in React Native stylesheet', fontFamilyRule)
|
||||
configureFont()
|
||||
}
|
||||
|
||||
if (filterBlurRule == null && rule.style.filter?.includes('blur(30px)')) {
|
||||
filterBlurRule = rule
|
||||
log('found filter: blur(30px) rule in React Native stylesheet', filterBlurRule)
|
||||
configureDynamicCss()
|
||||
}
|
||||
}
|
||||
|
||||
let elapsedTime = new Intl.NumberFormat(undefined).format(Date.now() - startTime)
|
||||
if (fontFamilyRule == null || filterBlurRule == null) {
|
||||
// Stop checking when there are no new rules since the last check
|
||||
if (lastRulesCount != $style.sheet.cssRules.length) {
|
||||
lastRulesCount = $style.sheet.cssRules.length
|
||||
log(`waiting for more React Native stylesheet rules (${lastRulesCount})`)
|
||||
setTimeout(findRules, 100)
|
||||
} else {
|
||||
warn(`stopped waiting for new React Native stylesheet rules after ${elapsedTime}ms (${lastRulesCount} rules)`)
|
||||
}
|
||||
} else {
|
||||
log(`finished checking React Native stylesheet in ${elapsedTime}ms (${lastRulesCount} rules)`)
|
||||
}
|
||||
}
|
||||
|
||||
findRules()
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures – or re-configures – the separated tweets timeline title.
|
||||
*
|
||||
@ -6270,16 +6311,17 @@ async function tweakDesktopLogo() {
|
||||
}
|
||||
|
||||
function tweakDisplaySettingsPage() {
|
||||
(async () => {
|
||||
void async function() {
|
||||
let $colorRerenderBoundary = await getElement('#react-root > div > div')
|
||||
|
||||
observeElement($colorRerenderBoundary, () => {
|
||||
let [newThemeColor, newAccent] = getThemeColorFromState()
|
||||
let [newThemeColor, newAccent, newHover] = getThemeColorFromState()
|
||||
if (newThemeColor == themeColor) return
|
||||
|
||||
log('Color setting changed')
|
||||
nativeThemeColor = newThemeColor
|
||||
nativeThemeColorAccent = newAccent
|
||||
nativeThemeColorHover = newHover
|
||||
themeColor = nativeThemeColor
|
||||
configureThemeCss()
|
||||
observePopups()
|
||||
@ -6288,7 +6330,7 @@ function tweakDisplaySettingsPage() {
|
||||
name: 'Color change re-render boundary',
|
||||
observers: pageObservers,
|
||||
})
|
||||
})()
|
||||
}()
|
||||
|
||||
if (desktop) {
|
||||
observeElement($html, () => {
|
||||
@ -7111,14 +7153,15 @@ async function main() {
|
||||
log('initial config', {enabled, config: settings, lang, version})
|
||||
|
||||
// One-time setup
|
||||
checkReactNativeStylesheet()
|
||||
observeBodyBackgroundColor()
|
||||
let [initialThemeColor, initialAccent] = getThemeColorFromState()
|
||||
let [initialThemeColor, initialAccent, initialHover] = getThemeColorFromState()
|
||||
if (initialThemeColor) {
|
||||
nativeThemeColor = initialThemeColor
|
||||
nativeThemeColorAccent = initialAccent
|
||||
nativeThemeColorHover = initialHover
|
||||
themeColor = nativeThemeColor
|
||||
}
|
||||
observeBodyBackgroundColor()
|
||||
observeReactNativeStylesheet()
|
||||
if (desktop) {
|
||||
fontSize = $html.style.fontSize
|
||||
if (!fontSize) {
|
||||
|
Loading…
Reference in New Issue
Block a user