tangled mirror of catsky-🐱 Soothing soft social-app fork with all the niche toggles! (Unofficial); for issues and PRs please put them on github:NekoDrone/catsky-social

refactor: redo theme and branding to fit catsky instead of bsky (#28)

* refactor: remove useTheme colour coupling

makes re-colouring easier

* refactor: like button theming

* refactor: okay alf is based

* refactor: style background overflow

* feat: determine base background by alf

* chore: editorconfig css

* refactor: lfgggg

finalised retheme and replaced logo

* refactor: provide temporary trending topics style

authored by serenity and committed by GitHub 170fe754 d5e30bc4

Changed files
+243 -138
assets
src
+1 -1
.editorconfig
··· 1 1 [*.{kt,kts}] 2 2 indent_size=2 3 3 4 - [*.{ts,tsx}] 4 + [*.{ts,tsx,css}] 5 5 indent_size=2
assets/favicon.png

This is a binary file and will not be displayed.

+49 -21
src/alf/themes.ts
··· 1 1 import {atoms} from '#/alf/atoms' 2 + import {mocha} from '#/alf/catppuccin/palette' 2 3 import {type Palette, type Theme} from '#/alf/types' 3 4 import { 4 5 BLUE_HUE, ··· 7 8 GREEN_HUE, 8 9 RED_HUE, 9 10 } from '#/alf/util/colorGeneration' 11 + import {fade} from '#/alf/util/colors' 10 12 11 13 const themes = createThemes({ 12 14 hues: { ··· 59 61 dark: Theme 60 62 dim: Theme 61 63 } { 64 + const accent = mocha.mauve 62 65 const color = { 63 66 like: '#ec4899', 64 67 trueBlack: '#000000', ··· 113 116 red_200: `hsl(${hues.negative}, 91%, 80%)`, 114 117 red_300: `hsl(${hues.negative}, 91%, 70%)`, 115 118 red_400: `hsl(${hues.negative}, 91%, 60%)`, 116 - red_500: `hsl(${hues.negative}, 91%, 50%)`, 119 + red_500: mocha.red, 117 120 red_600: `hsl(${hues.negative}, 91%, 42%)`, 118 121 red_700: `hsl(${hues.negative}, 91%, 34%)`, 119 122 red_800: `hsl(${hues.negative}, 91%, 26%)`, ··· 185 188 } as const 186 189 187 190 const darkPalette: Palette = { 188 - white: color.gray_25, 191 + white: mocha.text, 189 192 black: color.trueBlack, 190 193 like: color.like, 191 194 ··· 248 251 249 252 const dimPalette: Palette = { 250 253 ...darkPalette, 251 - black: `hsl(${hues.primary}, 28%, ${dimScale[0]}%)`, 252 - like: color.like, 254 + black: mocha.base, 255 + like: mocha.red, 253 256 254 - contrast_25: `hsl(${hues.primary}, 28%, ${dimScale[1]}%)`, 255 - contrast_50: `hsl(${hues.primary}, 28%, ${dimScale[2]}%)`, 256 - contrast_100: `hsl(${hues.primary}, 28%, ${dimScale[3]}%)`, 257 - contrast_200: `hsl(${hues.primary}, 28%, ${dimScale[4]}%)`, 257 + contrast_25: mocha.mantle, 258 + contrast_50: mocha.mantle, 259 + contrast_100: mocha.surface1, 260 + contrast_200: mocha.surface1, 258 261 contrast_300: `hsl(${hues.primary}, 24%, ${dimScale[5]}%)`, 259 262 contrast_400: `hsl(${hues.primary}, 24%, ${dimScale[6]}%)`, 260 263 contrast_500: `hsl(${hues.primary}, 20%, ${dimScale[7]}%)`, ··· 266 269 contrast_975: `hsl(${hues.primary}, 20%, ${dimScale[13]}%)`, 267 270 268 271 primary_25: `hsl(${hues.primary}, 50%, ${dimScale[1]}%)`, 269 - primary_50: `hsl(${hues.primary}, 60%, ${dimScale[2]}%)`, 272 + primary_50: fade(accent, 15), 270 273 primary_100: `hsl(${hues.primary}, 70%, ${dimScale[3]}%)`, 271 274 primary_200: `hsl(${hues.primary}, 82%, ${dimScale[4]}%)`, 272 275 primary_300: `hsl(${hues.primary}, 90%, ${dimScale[5]}%)`, 273 276 primary_400: `hsl(${hues.primary}, 95%, ${dimScale[6]}%)`, 274 - primary_500: `hsl(${hues.primary}, 99%, ${dimScale[7]}%)`, 277 + primary_500: accent, 275 278 primary_600: `hsl(${hues.primary}, 99%, ${dimScale[8]}%)`, 276 279 primary_700: `hsl(${hues.primary}, 99%, ${dimScale[9]}%)`, 277 280 primary_800: `hsl(${hues.primary}, 99%, ${dimScale[10]}%)`, ··· 284 287 positive_100: `hsl(${hues.positive}, 70%, ${dimScale[3]}%)`, 285 288 positive_200: `hsl(${hues.positive}, 82%, ${dimScale[4]}%)`, 286 289 positive_300: `hsl(${hues.positive}, 82%, ${dimScale[5]}%)`, 287 - positive_400: `hsl(${hues.positive}, 82%, ${dimScale[6]}%)`, 288 - positive_500: `hsl(${hues.positive}, 82%, ${dimScale[7]}%)`, 289 - positive_600: `hsl(${hues.positive}, 82%, ${dimScale[8]}%)`, 290 + positive_400: mocha.green, 291 + positive_500: mocha.green, 292 + positive_600: mocha.green, 290 293 positive_700: `hsl(${hues.positive}, 82%, ${dimScale[9]}%)`, 291 294 positive_800: `hsl(${hues.positive}, 82%, ${dimScale[10]}%)`, 292 295 positive_900: `hsl(${hues.positive}, 82%, ${dimScale[11]}%)`, ··· 298 301 negative_100: `hsl(${hues.negative}, 84%, ${dimScale[3]}%)`, 299 302 negative_200: `hsl(${hues.negative}, 88%, ${dimScale[4]}%)`, 300 303 negative_300: `hsl(${hues.negative}, 91%, ${dimScale[5]}%)`, 301 - negative_400: `hsl(${hues.negative}, 91%, ${dimScale[6]}%)`, 302 - negative_500: `hsl(${hues.negative}, 91%, ${dimScale[7]}%)`, 303 - negative_600: `hsl(${hues.negative}, 91%, ${dimScale[8]}%)`, 304 + negative_400: mocha.red, 305 + negative_500: mocha.red, 306 + negative_600: mocha.red, 304 307 negative_700: `hsl(${hues.negative}, 91%, ${dimScale[9]}%)`, 305 308 negative_800: `hsl(${hues.negative}, 91%, ${dimScale[10]}%)`, 306 309 negative_900: `hsl(${hues.negative}, 91%, ${dimScale[11]}%)`, ··· 390 393 shadow_lg: { 391 394 ...atoms.shadow_lg, 392 395 shadowColor: lightPalette.black, 396 + }, // TODO: probably delete this when we shift to setting CTP colours. 397 + trending_hot: { 398 + color: '#FFFFFF', 399 + backgroundColor: 'red', 400 + }, 401 + trending_new: { 402 + color: '#FFFFFF', 403 + backgroundColor: 'green', 393 404 }, 394 405 }, 395 406 } ··· 480 491 shadowOpacity: 0.7, 481 492 shadowColor: color.trueBlack, 482 493 }, 494 + // TODO: probably delete this when we shift to setting CTP colours. 495 + trending_hot: { 496 + color: '#FFFFFF', 497 + backgroundColor: 'red', 498 + }, 499 + trending_new: { 500 + color: '#FFFFFF', 501 + backgroundColor: 'green', 502 + }, 483 503 }, 484 504 } 485 505 ··· 491 511 atoms: { 492 512 ...dark.atoms, 493 513 text: { 494 - color: dimPalette.white, 514 + color: mocha.text, 495 515 }, 496 516 text_contrast_low: { 497 - color: dimPalette.contrast_400, 517 + color: mocha.overlay0, 498 518 }, 499 519 text_contrast_medium: { 500 - color: dimPalette.contrast_600, 520 + color: mocha.overlay2, 501 521 }, 502 522 text_contrast_high: { 503 - color: dimPalette.contrast_900, 523 + color: mocha.subtext0, 504 524 }, 505 525 text_inverted: { 506 - color: dimPalette.black, 526 + color: mocha.crust, 507 527 }, 508 528 bg: { 509 529 backgroundColor: dimPalette.black, ··· 570 590 ...atoms.shadow_lg, 571 591 shadowOpacity: 0.7, 572 592 shadowColor: `hsl(${hues.primary}, 28%, 6%)`, 593 + }, 594 + trending_hot: { 595 + color: mocha.crust, 596 + backgroundColor: mocha.red, 597 + }, 598 + trending_new: { 599 + color: mocha.crust, 600 + backgroundColor: mocha.green, 573 601 }, 574 602 }, 575 603 }
+8
src/alf/types.ts
··· 155 155 elevation: number 156 156 shadowColor: string 157 157 } 158 + trending_hot: { 159 + color: string 160 + backgroundColor: string 161 + } 162 + trending_new: { 163 + color: string 164 + backgroundColor: string 165 + } 158 166 } 159 167 export type Theme = { 160 168 scheme: 'light' | 'dark' // for library support
+1
src/alf/util/useColorModeTheme.ts
··· 49 49 // remove any other color mode classes 50 50 html.className = html.className.replace(/(theme)--\w+/g, '') 51 51 html.classList.add(`theme--${theme}`) 52 + html.style.backgroundColor = getBackgroundColor(theme) 52 53 // set color to 'theme-color' meta tag 53 54 meta?.setAttribute('content', getBackgroundColor(theme)) 54 55 }
+1 -1
src/components/Button.tsx
··· 591 591 if (variant === 'solid') { 592 592 if (color === 'primary') { 593 593 if (!disabled) { 594 - baseStyles.push({color: t.palette.white}) 594 + baseStyles.push(t.atoms.text_inverted) 595 595 } else { 596 596 baseStyles.push({ 597 597 color: select(t.name, {
+2 -3
src/lib/custom-animations/CountWheel.tsx
··· 8 8 } from 'react-native-reanimated' 9 9 10 10 import {decideShouldRoll} from '#/lib/custom-animations/util' 11 - import {s} from '#/lib/styles' 12 11 import {Text} from '#/view/com/util/text/Text' 13 12 import {atoms as a, useTheme} from '#/alf' 14 13 import {useFormatPostStatCount} from '#/components/PostControls/util' ··· 147 146 big ? a.text_md : a.text_sm, 148 147 a.user_select_none, 149 148 isLiked 150 - ? [a.font_bold, s.likeColor] 149 + ? [a.font_bold, {color: t.palette.like}] 151 150 : {color: t.palette.contrast_500}, 152 151 ]}> 153 152 {formattedCount} ··· 165 164 big ? a.text_md : a.text_sm, 166 165 a.user_select_none, 167 166 isLiked 168 - ? [a.font_bold, s.likeColor] 167 + ? [a.font_bold, {color: t.palette.like}] 169 168 : {color: t.palette.contrast_500}, 170 169 ]}> 171 170 {formattedPrevCount}
+2 -3
src/lib/custom-animations/CountWheel.web.tsx
··· 3 3 import {useReducedMotion} from 'react-native-reanimated' 4 4 5 5 import {decideShouldRoll} from '#/lib/custom-animations/util' 6 - import {s} from '#/lib/styles' 7 6 import {Text} from '#/view/com/util/text/Text' 8 7 import {atoms as a, useTheme} from '#/alf' 9 8 import {useFormatPostStatCount} from '#/components/PostControls/util' ··· 93 92 big ? a.text_md : a.text_sm, 94 93 a.user_select_none, 95 94 isLiked 96 - ? [a.font_bold, s.likeColor] 95 + ? [a.font_bold, {color: t.palette.like}] 97 96 : {color: t.palette.contrast_500}, 98 97 ]}> 99 98 {formattedCount} ··· 110 109 big ? a.text_md : a.text_sm, 111 110 a.user_select_none, 112 111 isLiked 113 - ? [a.font_bold, s.likeColor] 112 + ? [a.font_bold, {color: t.palette.like}] 114 113 : {color: t.palette.contrast_500}, 115 114 ]}> 116 115 {formattedPrevCount}
+2 -3
src/lib/custom-animations/LikeIcon.tsx
··· 5 5 useReducedMotion, 6 6 } from 'react-native-reanimated' 7 7 8 - import {s} from '#/lib/styles' 9 8 import {useTheme} from '#/alf' 10 9 import { 11 10 Heart2_Filled_Stroke2_Corner0_Rounded as HeartIconFilled, ··· 86 85 {isLiked ? ( 87 86 <Animated.View 88 87 entering={shouldAnimate ? keyframe.duration(300) : undefined}> 89 - <HeartIconFilled style={s.likeColor} width={size} /> 88 + <HeartIconFilled style={{color: t.palette.like}} width={size} /> 90 89 </Animated.View> 91 90 ) : ( 92 91 <HeartIconOutline ··· 100 99 entering={circle1Keyframe.duration(300)} 101 100 style={{ 102 101 position: 'absolute', 103 - backgroundColor: s.likeColor.color, 102 + backgroundColor: t.palette.like, 104 103 top: 0, 105 104 left: 0, 106 105 width: size,
+2 -3
src/lib/custom-animations/LikeIcon.web.tsx
··· 2 2 import {View} from 'react-native' 3 3 import {useReducedMotion} from 'react-native-reanimated' 4 4 5 - import {s} from '#/lib/styles' 6 5 import {useTheme} from '#/alf' 7 6 import { 8 7 Heart2_Filled_Stroke2_Corner0_Rounded as HeartIconFilled, ··· 74 73 {isLiked ? ( 75 74 // @ts-expect-error is div 76 75 <View ref={likeIconRef}> 77 - <HeartIconFilled style={s.likeColor} width={size} /> 76 + <HeartIconFilled style={{color: t.palette.like}} width={size} /> 78 77 </View> 79 78 ) : ( 80 79 <HeartIconOutline ··· 87 86 ref={circle1Ref} 88 87 style={{ 89 88 position: 'absolute', 90 - backgroundColor: s.likeColor.color, 89 + backgroundColor: t.palette.like, 91 90 top: 0, 92 91 left: 0, 93 92 width: size,
+3 -3
src/lib/hooks/useColorSchemeStyle.ts
··· 1 - import {useTheme} from '#/lib/ThemeContext' 1 + import {useColorModeTheme} from '#/alf/util/useColorModeTheme' 2 2 3 3 export function useColorSchemeStyle<T>(lightStyle: T, darkStyle: T) { 4 - const colorScheme = useTheme().colorScheme 5 - return colorScheme === 'dark' ? darkStyle : lightStyle 4 + const colorMode = useColorModeTheme() 5 + return colorMode === 'dark' ? darkStyle : lightStyle 6 6 }
+4 -6
src/screens/Search/modules/ExploreTrendingTopics.tsx
··· 184 184 } 185 185 case 'hot': { 186 186 Icon = FlameIcon 187 - color = 188 - t.scheme === 'light' ? t.palette.negative_500 : t.palette.negative_950 189 - backgroundColor = 190 - t.scheme === 'light' ? t.palette.negative_50 : t.palette.negative_200 187 + color = t.atoms.trending_hot.color 188 + backgroundColor = t.atoms.trending_hot.backgroundColor 191 189 text = _(msg`Hot`) 192 190 break 193 191 } 194 192 case 'new': { 195 193 Icon = TrendingIcon 196 194 text = _(msg`New`) 197 - color = t.palette.positive_700 198 - backgroundColor = t.palette.positive_50 195 + color = t.atoms.trending_new.color 196 + backgroundColor = t.atoms.trending_new.backgroundColor 199 197 break 200 198 } 201 199 default: {
+41 -3
src/style.css
··· 16 16 --background: white; 17 17 --backgroundLight: hsl(211, 20%, 95%); 18 18 } 19 + 19 20 @media (prefers-color-scheme: dark) { 20 21 :root { 21 22 color-scheme: dark; ··· 29 30 --text: black; 30 31 --background: white; 31 32 --backgroundLight: hsl(211, 20%, 95%); 32 - background-color: white; 33 33 } 34 + 34 35 html.theme--dark { 35 36 color-scheme: dark; 36 - background-color: black; 37 37 --text: white; 38 38 --background: black; 39 39 --backgroundLight: hsl(211, 20%, 20%); 40 40 } 41 + 41 42 html.theme--dim { 42 43 color-scheme: dark; 43 - background-color: hsl(211, 28%, 12%); 44 44 --text: white; 45 45 --background: hsl(211, 20%, 4%); 46 46 --backgroundLight: hsl(211, 20%, 10%); ··· 67 67 background: var(--background); 68 68 color: var(--text); 69 69 } 70 + 70 71 /* Force left-align date/time inputs on iOS mobile */ 71 72 input::-webkit-date-and-time-value { 72 73 text-align: left; ··· 76 77 a { 77 78 color: inherit; 78 79 } 80 + 79 81 a[role='link']:hover { 80 82 text-decoration: underline; 81 83 } 84 + 82 85 a[role='link'][data-no-underline='1']:hover { 83 86 text-decoration: none; 84 87 } ··· 87 90 *[data-word-wrap] { 88 91 word-break: break-word; 89 92 } 93 + 90 94 *[data-stable-gutters] { 91 95 scrollbar-gutter: stable both-edges; 92 96 } ··· 95 99 .ProseMirror { 96 100 min-height: inherit; 97 101 } 102 + 98 103 .ProseMirror-dark { 99 104 color: white; 100 105 } 106 + 101 107 .ProseMirror p { 102 108 margin: 0; 103 109 } 110 + 104 111 .ProseMirror p.is-editor-empty:first-child::before { 105 112 color: #8d8e96; 106 113 content: attr(data-placeholder); ··· 108 115 height: 0; 109 116 pointer-events: none; 110 117 } 118 + 111 119 .ProseMirror .mention { 112 120 color: #0085ff; 113 121 } 122 + 114 123 .ProseMirror a, 115 124 .ProseMirror .autolink { 116 125 color: #0085ff; 117 126 } 127 + 118 128 /* OLLIE: TODO -- this is not accessible */ 119 129 /* Remove focus state on inputs */ 120 130 .ProseMirror-focused { 121 131 outline: 0; 122 132 } 133 + 123 134 textarea:focus, 124 135 input:focus { 125 136 outline: 0; 126 137 } 138 + 127 139 .tippy-content .items { 128 140 width: fit-content; 129 141 } ··· 133 145 position: relative; 134 146 z-index: 10; 135 147 } 148 + 136 149 [data-tooltip]::after { 137 150 content: attr(data-tooltip); 138 151 display: none; ··· 149 162 font-size: 12px; 150 163 z-index: 10; 151 164 } 165 + 152 166 [data-tooltip]::before { 153 167 content: ''; 154 168 display: none; ··· 161 175 transform: translateY(100%) translateY(2px) translateX(-50%); 162 176 z-index: 10; 163 177 } 178 + 164 179 [data-tooltip]:hover::after, 165 180 [data-tooltip]:hover::before { 166 181 display: block; ··· 177 192 0% { 178 193 transform: rotate(0deg); 179 194 } 195 + 180 196 100% { 181 197 transform: rotate(360deg); 182 198 } 183 199 } 200 + 184 201 .rotate-500ms { 185 202 position: absolute; 186 203 inset: 0; ··· 192 209 from { 193 210 opacity: 0; 194 211 } 212 + 195 213 to { 196 214 opacity: 1; 197 215 } ··· 201 219 from { 202 220 opacity: 1; 203 221 } 222 + 204 223 to { 205 224 opacity: 0; 206 225 } ··· 210 229 from { 211 230 transform: scale(0.95); 212 231 } 232 + 213 233 to { 214 234 transform: scale(1); 215 235 } ··· 219 239 from { 220 240 transform: translateX(-100%); 221 241 } 242 + 222 243 to { 223 244 transform: translateX(0); 224 245 } ··· 228 249 from { 229 250 transform: translateX(0); 230 251 } 252 + 231 253 to { 232 254 transform: translateX(-100%); 233 255 } ··· 237 259 .dropdown-menu-transform-origin > * { 238 260 transform-origin: var(--radix-dropdown-menu-content-transform-origin); 239 261 } 262 + 240 263 .dropdown-menu-constrain-size > * { 241 264 max-height: var(--radix-dropdown-menu-content-available-height); 242 265 } ··· 298 321 cursor: pointer; 299 322 border: 1px solid transparent; 300 323 } 324 + 301 325 .EmojiReactionPicker__Pressable:focus { 302 326 outline: none; 303 327 border-color: var(--text); 304 328 } 329 + 305 330 .EmojiReactionPicker__Pressable:hover { 306 331 outline: none; 307 332 transform: scale(1.1); 308 333 border-color: transparent; 309 334 } 335 + 310 336 .EmojiReactionPicker__Pressable:not(.__selected).__disabled { 311 337 transform: scale(1) !important; 312 338 border-color: transparent !important; 313 339 opacity: 0.7; 314 340 } 341 + 315 342 .EmojiReactionPicker__Pressable ~ button { 316 343 cursor: pointer; 317 344 border: 1px solid transparent; 318 345 } 346 + 319 347 .EmojiReactionPicker__Pressable ~ button:focus { 320 348 outline: none; 321 349 border-color: var(--text); 322 350 } 351 + 323 352 .EmojiReactionPicker__Pressable ~ button:hover { 324 353 outline: none; 325 354 background-color: var(--backgroundLight); ··· 343 372 animation-timing-function: cubic-bezier(0.17, 0.73, 0.14, 1); 344 373 will-change: transform, opacity; 345 374 } 375 + 346 376 .radix-popover-content[data-state='open'][data-side='top'] { 347 377 animation-name: radixPopoverSlideUpAndFade; 348 378 } 379 + 349 380 .radix-popover-content[data-state='open'][data-side='bottom'] { 350 381 animation-name: radixPopoverSlideDownAndFade; 351 382 } 383 + 352 384 @keyframes radixPopoverSlideUpAndFade { 353 385 from { 354 386 opacity: 0; 355 387 transform: translateY(2px); 356 388 } 389 + 357 390 to { 358 391 opacity: 1; 359 392 transform: translateY(0); 360 393 } 361 394 } 395 + 362 396 @keyframes radixPopoverSlideDownAndFade { 363 397 from { 364 398 opacity: 0; 365 399 transform: translateY(-2px); 366 400 } 401 + 367 402 to { 368 403 opacity: 1; 369 404 transform: translateY(0); ··· 377 412 from { 378 413 opacity: 0; 379 414 } 415 + 380 416 to { 381 417 opacity: 1; 382 418 } 383 419 } 420 + 384 421 @keyframes toastFadeOut { 385 422 from { 386 423 opacity: 1; 387 424 } 425 + 388 426 to { 389 427 opacity: 0; 390 428 }
+3 -3
src/view/com/composer/text-input/TextInput.tsx
··· 22 22 import {isUriImage} from '#/lib/media/util' 23 23 import {cleanError} from '#/lib/strings/errors' 24 24 import {getMentionAt, insertMentionAt} from '#/lib/strings/mention-manip' 25 - import {useTheme} from '#/lib/ThemeContext' 26 25 import {isAndroid, isNative} from '#/platform/detection' 27 26 import { 28 27 type LinkFacetMatch, ··· 30 29 } from '#/view/com/composer/text-input/text-input-util' 31 30 import {atoms as a, useAlf} from '#/alf' 32 31 import {normalizeTextStyles} from '#/alf/typography' 32 + import {useColorModeTheme} from '#/alf/util/useColorModeTheme' 33 33 import {Autocomplete} from './mobile/Autocomplete' 34 34 import {type TextInputProps} from './TextInput.types' 35 35 ··· 52 52 const {theme: t, fonts} = useAlf() 53 53 const textInput = useRef<PasteInputRef>(null) 54 54 const textInputSelection = useRef<Selection>({start: 0, end: 0}) 55 - const theme = useTheme() 55 + const colorMode = useColorModeTheme() 56 56 const [autocompletePrefix, setAutocompletePrefix] = useState('') 57 57 const prevLength = useRef(richtext.length) 58 58 ··· 223 223 onSelectionChange={onSelectionChange} 224 224 placeholder={placeholder} 225 225 placeholderTextColor={t.atoms.text_contrast_medium.color} 226 - keyboardAppearance={theme.colorScheme} 226 + keyboardAppearance={colorMode} 227 227 autoFocus={true} 228 228 allowFontScaling 229 229 multiline
+1 -1
src/view/com/home/HomeHeaderLayout.web.tsx
··· 49 49 style={[a.flex_row, a.align_center, gutters, a.pt_md, t.atoms.bg]}> 50 50 <View style={{width: 34}} /> 51 51 <View style={[a.flex_1, a.align_center, a.justify_center]}> 52 - <Logo width={kawaii ? 60 : 28} /> 52 + <Logo width={kawaii ? 60 : 48} /> 53 53 </View> 54 54 <Link 55 55 to="/feeds"
+32 -27
src/view/com/util/forms/Button.tsx
··· 14 14 } from 'react-native' 15 15 16 16 import {choose} from '#/lib/functions' 17 - import {useTheme} from '#/lib/ThemeContext' 17 + import {useTheme} from '#/alf' 18 + import {useColorModeTheme} from '#/alf/util/useColorModeTheme' 18 19 import {Text} from '../text/Text' 19 20 20 21 export type ButtonType = ··· 71 72 disabled?: boolean 72 73 }>) { 73 74 const theme = useTheme() 75 + const colorMode = useColorModeTheme() 74 76 const typeOuterStyle = choose<ViewStyle, Record<ButtonType, ViewStyle>>( 75 77 type, 76 78 { 77 79 primary: { 78 - backgroundColor: theme.palette.primary.background, 80 + backgroundColor: theme.palette.primary_500, 79 81 }, 80 82 secondary: { 81 - backgroundColor: theme.palette.secondary.background, 83 + backgroundColor: theme.palette.positive_500, 82 84 }, 83 85 default: { 84 - backgroundColor: theme.palette.default.backgroundLight, 86 + backgroundColor: theme.palette.contrast_25, 85 87 }, 86 88 inverted: { 87 - backgroundColor: theme.palette.inverted.background, 89 + backgroundColor: 90 + colorMode === 'light' ? theme.palette.black : theme.palette.white, 88 91 }, 89 92 'primary-outline': { 90 - backgroundColor: theme.palette.default.background, 93 + backgroundColor: 94 + colorMode === 'light' ? theme.palette.white : theme.palette.black, 91 95 borderWidth: 1, 92 - borderColor: theme.palette.primary.border, 96 + borderColor: theme.palette.primary_600, 93 97 }, 94 98 'secondary-outline': { 95 - backgroundColor: theme.palette.default.background, 99 + backgroundColor: 100 + colorMode === 'light' ? theme.palette.white : theme.palette.black, 96 101 borderWidth: 1, 97 - borderColor: theme.palette.secondary.border, 102 + borderColor: theme.palette.positive_600, 98 103 }, 99 104 'primary-light': { 100 - backgroundColor: theme.palette.default.background, 105 + backgroundColor: 106 + colorMode === 'light' ? theme.palette.white : theme.palette.black, 101 107 }, 102 108 'secondary-light': { 103 - backgroundColor: theme.palette.default.background, 109 + backgroundColor: 110 + colorMode === 'light' ? theme.palette.white : theme.palette.black, 104 111 }, 105 112 'default-light': { 106 - backgroundColor: theme.palette.default.background, 113 + backgroundColor: 114 + colorMode === 'light' ? theme.palette.white : theme.palette.black, 107 115 }, 108 116 }, 109 117 ) ··· 111 119 type, 112 120 { 113 121 primary: { 114 - color: theme.palette.primary.text, 122 + color: theme.palette.white, 115 123 fontWeight: '600', 116 124 }, 117 125 secondary: { 118 - color: theme.palette.secondary.text, 119 - fontWeight: theme.palette.secondary.isLowContrast ? '600' : undefined, 126 + color: theme.palette.white, 120 127 }, 121 128 default: { 122 - color: theme.palette.default.text, 129 + color: 130 + colorMode === 'light' ? theme.palette.white : theme.palette.black, 123 131 }, 124 132 inverted: { 125 - color: theme.palette.inverted.text, 133 + color: 134 + colorMode === 'light' ? theme.palette.black : theme.palette.white, 126 135 fontWeight: '600', 127 136 }, 128 137 'primary-outline': { 129 - color: theme.palette.primary.textInverted, 130 - fontWeight: theme.palette.primary.isLowContrast ? '600' : undefined, 138 + color: theme.palette.primary_500, 131 139 }, 132 140 'secondary-outline': { 133 - color: theme.palette.secondary.textInverted, 134 - fontWeight: theme.palette.secondary.isLowContrast ? '600' : undefined, 141 + color: theme.palette.positive_600, 135 142 }, 136 143 'primary-light': { 137 - color: theme.palette.primary.textInverted, 138 - fontWeight: theme.palette.primary.isLowContrast ? '600' : undefined, 144 + color: theme.palette.primary_500, 139 145 }, 140 146 'secondary-light': { 141 - color: theme.palette.secondary.textInverted, 142 - fontWeight: theme.palette.secondary.isLowContrast ? '600' : undefined, 147 + color: theme.palette.positive_600, 143 148 }, 144 149 'default-light': { 145 - color: theme.palette.default.text, 146 - fontWeight: theme.palette.default.isLowContrast ? '600' : undefined, 150 + color: 151 + colorMode === 'light' ? theme.palette.white : theme.palette.black, 147 152 }, 148 153 }, 149 154 )
+40 -37
src/view/com/util/forms/ToggleButton.tsx
··· 8 8 9 9 import {choose} from '#/lib/functions' 10 10 import {colors} from '#/lib/styles' 11 - import {useTheme} from '#/lib/ThemeContext' 12 11 import {type TypographyVariant} from '#/lib/ThemeContext' 12 + import {useTheme} from '#/alf' 13 + import {useColorModeTheme} from '#/alf/util/useColorModeTheme' 13 14 import {Text} from '../text/Text' 14 15 import {Button, type ButtonType} from './Button' 15 16 ··· 34 35 onPress?: () => void 35 36 }) { 36 37 const theme = useTheme() 38 + const colorMode = useColorModeTheme() 37 39 const circleStyle = choose<TextStyle, Record<ButtonType, TextStyle>>(type, { 38 40 primary: { 39 - borderColor: theme.palette.primary.text, 41 + borderColor: theme.palette.primary_500, 40 42 }, 41 43 secondary: { 42 - borderColor: theme.palette.secondary.text, 44 + borderColor: theme.palette.positive_600, 43 45 }, 44 46 inverted: { 45 - borderColor: theme.palette.inverted.text, 47 + borderColor: 48 + colorMode === 'light' ? theme.palette.white : theme.palette.black, 46 49 }, 47 50 'primary-outline': { 48 - borderColor: theme.palette.primary.border, 51 + borderColor: theme.palette.primary_500, 49 52 }, 50 53 'secondary-outline': { 51 - borderColor: theme.palette.secondary.border, 54 + borderColor: theme.palette.positive_600, 52 55 }, 53 56 'primary-light': { 54 - borderColor: theme.palette.primary.border, 57 + borderColor: theme.palette.primary_500, 55 58 }, 56 59 'secondary-light': { 57 - borderColor: theme.palette.secondary.border, 60 + borderColor: theme.palette.positive_600, 58 61 }, 59 62 default: { 60 - borderColor: theme.palette.default.border, 63 + borderColor: 64 + colorMode === 'light' ? theme.palette.white : theme.palette.black, 61 65 }, 62 66 'default-light': { 63 - borderColor: theme.palette.default.border, 67 + borderColor: 68 + colorMode === 'light' ? theme.palette.white : theme.palette.black, 64 69 }, 65 70 }) 66 71 const circleFillStyle = choose<TextStyle, Record<ButtonType, TextStyle>>( 67 72 type, 68 73 { 69 74 primary: { 70 - backgroundColor: theme.palette.primary.text, 75 + backgroundColor: theme.palette.primary_500, 71 76 opacity: isSelected ? 1 : 0.33, 72 77 }, 73 78 secondary: { 74 - backgroundColor: theme.palette.secondary.text, 79 + backgroundColor: theme.palette.positive_600, 75 80 opacity: isSelected ? 1 : 0.33, 76 81 }, 77 82 inverted: { 78 - backgroundColor: theme.palette.inverted.text, 83 + backgroundColor: 84 + colorMode === 'light' ? theme.palette.white : theme.palette.black, 79 85 opacity: isSelected ? 1 : 0.33, 80 86 }, 81 87 'primary-outline': { 82 - backgroundColor: theme.palette.primary.background, 88 + backgroundColor: 89 + colorMode === 'light' ? theme.palette.black : theme.palette.white, 83 90 opacity: isSelected ? 1 : 0.5, 84 91 }, 85 92 'secondary-outline': { 86 - backgroundColor: theme.palette.secondary.background, 93 + backgroundColor: theme.palette.positive_500, 87 94 opacity: isSelected ? 1 : 0.5, 88 95 }, 89 96 'primary-light': { 90 - backgroundColor: theme.palette.primary.background, 97 + backgroundColor: 98 + colorMode === 'light' ? theme.palette.black : theme.palette.white, 91 99 opacity: isSelected ? 1 : 0.5, 92 100 }, 93 101 'secondary-light': { 94 - backgroundColor: theme.palette.secondary.background, 102 + backgroundColor: theme.palette.positive_500, 95 103 opacity: isSelected ? 1 : 0.5, 96 104 }, 97 105 default: { 98 106 backgroundColor: isSelected 99 - ? theme.palette.primary.background 107 + ? colorMode === 'light' 108 + ? theme.palette.black 109 + : theme.palette.white 100 110 : colors.gray3, 101 111 }, 102 112 'default-light': { 103 113 backgroundColor: isSelected 104 - ? theme.palette.primary.background 114 + ? colorMode === 'light' 115 + ? theme.palette.black 116 + : theme.palette.white 105 117 : colors.gray3, 106 118 }, 107 119 }, 108 120 ) 109 121 const labelStyle = choose<TextStyle, Record<ButtonType, TextStyle>>(type, { 110 122 primary: { 111 - color: theme.palette.primary.text, 112 - fontWeight: theme.palette.primary.isLowContrast ? '600' : undefined, 123 + color: theme.palette.primary_500, 113 124 }, 114 125 secondary: { 115 - color: theme.palette.secondary.text, 116 - fontWeight: theme.palette.secondary.isLowContrast ? '600' : undefined, 126 + color: theme.palette.positive_600, 117 127 }, 118 128 inverted: { 119 - color: theme.palette.inverted.text, 120 - fontWeight: theme.palette.inverted.isLowContrast ? '600' : undefined, 129 + color: colorMode === 'light' ? theme.palette.white : theme.palette.black, 121 130 }, 122 131 'primary-outline': { 123 - color: theme.palette.primary.textInverted, 124 - fontWeight: theme.palette.primary.isLowContrast ? '600' : undefined, 132 + color: theme.palette.primary_500, 125 133 }, 126 134 'secondary-outline': { 127 - color: theme.palette.secondary.textInverted, 128 - fontWeight: theme.palette.secondary.isLowContrast ? '600' : undefined, 135 + color: theme.palette.positive_600, 129 136 }, 130 137 'primary-light': { 131 - color: theme.palette.primary.textInverted, 132 - fontWeight: theme.palette.primary.isLowContrast ? '600' : undefined, 138 + color: theme.palette.primary_500, 133 139 }, 134 140 'secondary-light': { 135 - color: theme.palette.secondary.textInverted, 136 - fontWeight: theme.palette.secondary.isLowContrast ? '600' : undefined, 141 + color: theme.palette.positive_600, 137 142 }, 138 143 default: { 139 - color: theme.palette.default.text, 140 - fontWeight: theme.palette.default.isLowContrast ? '600' : undefined, 144 + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, 141 145 }, 142 146 'default-light': { 143 - color: theme.palette.default.text, 144 - fontWeight: theme.palette.default.isLowContrast ? '600' : undefined, 147 + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, 145 148 }, 146 149 }) 147 150 return (
+49 -21
src/view/icons/Logo.tsx
··· 1 1 import React from 'react' 2 2 import {StyleSheet, type TextProps} from 'react-native' 3 - import Svg, { 4 - Defs, 5 - LinearGradient, 6 - Path, 7 - type PathProps, 8 - Stop, 9 - type SvgProps, 10 - } from 'react-native-svg' 3 + import Svg, {Path, type PathProps, type SvgProps} from 'react-native-svg' 11 4 import {Image} from 'expo-image' 12 5 13 - import {colors} from '#/lib/styles' 14 6 import {useKawaiiMode} from '#/state/preferences/kawaii' 7 + import {useTheme} from '#/alf' 15 8 16 9 const ratio = 57 / 64 17 10 ··· 21 14 } & Omit<SvgProps, 'style'> 22 15 23 16 export const Logo = React.forwardRef(function LogoImpl(props: Props, ref) { 17 + const theme = useTheme() 24 18 const {fill, ...rest} = props 25 19 const gradient = fill === 'sky' 26 20 const styles = StyleSheet.flatten(props.style) 27 - const _fill = gradient ? 'url(#sky)' : fill || styles?.color || colors.blue3 21 + const _fill = gradient 22 + ? 'url(#sky)' 23 + : fill || styles?.color || theme.palette.primary_500 28 24 // @ts-ignore it's fiiiiine 29 25 const size = parseInt(rest.width || 32) 30 26 ··· 51 47 fill="none" 52 48 // @ts-ignore it's fiiiiine 53 49 ref={ref} 54 - viewBox="0 0 64 57" 50 + viewBox="0 0 64 64" 55 51 {...rest} 56 52 style={[{width: size, height: size * ratio}, styles]}> 57 - {gradient && ( 58 - <Defs> 59 - <LinearGradient id="sky" x1="0" y1="0" x2="0" y2="1"> 60 - <Stop offset="0" stopColor="#0A7AFF" stopOpacity="1" /> 61 - <Stop offset="1" stopColor="#59B9FF" stopOpacity="1" /> 62 - </LinearGradient> 63 - </Defs> 64 - )} 65 - 53 + <Path 54 + fill={_fill} 55 + d="m 16.161994,43.872871 -1.224499,0.795377 -0.0039,0.0043 c -0.405665,0.279253 -0.757072,0.557439 -1.016381,0.802797 -0.129655,0.122679 -0.235296,0.233057 -0.326039,0.359227 -0.04537,0.06309 -0.0887,0.126173 -0.129634,0.236232 -0.04093,0.110061 -0.09462,0.33528 0.01718,0.566174 l 0.06677,0.13432 c 0.11174,0.230754 0.299833,0.287449 0.400226,0.300268 0.100392,0.01282 0.168112,0.0016 0.236621,-0.01367 0.13702,-0.03054 0.269343,-0.0845 0.423265,-0.156966 0.305048,-0.143632 0.681622,-0.365405 1.083151,-0.641145 l 0.0098,-0.007 1.398256,-0.910174 c -0.34456,-0.477079 -0.657218,-0.967676 -0.934774,-1.46971 z" 56 + id="path71" 57 + /> 66 58 <Path 67 59 fill={_fill} 68 - d="M13.873 3.805C21.21 9.332 29.103 20.537 32 26.55v15.882c0-.338-.13.044-.41.867-1.512 4.456-7.418 21.847-20.923 7.944-7.111-7.32-3.819-14.64 9.125-16.85-7.405 1.264-15.73-.825-18.014-9.015C1.12 23.022 0 8.51 0 6.55 0-3.268 8.579-.182 13.873 3.805ZM50.127 3.805C42.79 9.332 34.897 20.537 32 26.55v15.882c0-.338.13.044.41.867 1.512 4.456 7.418 21.847 20.923 7.944 7.111-7.32 3.819-14.64-9.125-16.85 7.405 1.264 15.73-.825 18.014-9.015C62.88 23.022 64 8.51 64 6.55c0-9.818-8.578-6.732-13.873-2.745Z" 60 + d="m 51.539309,43.851788 c -0.282687,0.498915 -0.600627,0.986328 -0.950783,1.46034 l 1.455263,0.947658 c 0.401529,0.275739 0.778103,0.497513 1.083151,0.641145 0.153922,0.07248 0.286244,0.126425 0.423264,0.156966 0.06851,0.01527 0.138182,0.02649 0.238575,0.01367 0.09983,-0.01275 0.286702,-0.07037 0.398664,-0.297925 l 0.002,-0.0023 0.06481,-0.13432 h 0.002 c 0.111803,-0.230893 0.05811,-0.456116 0.01718,-0.566174 -0.04093,-0.110061 -0.08426,-0.173147 -0.129635,-0.236232 -0.09075,-0.126171 -0.196774,-0.236548 -0.326429,-0.359227 -0.259395,-0.245389 -0.6108,-0.523574 -1.016467,-0.802827 l -0.0055,-0.0047 z" 61 + id="path62" 62 + /> 63 + <Path 64 + fill={_fill} 65 + d="m 52.980515,39.692944 c -0.08276,0.616433 -0.22187,1.225255 -0.412331,1.823472 h 1.920698 c 0.468509,0 0.890886,-0.0325 1.218251,-0.09058 0.163684,-0.02904 0.301569,-0.06068 0.433026,-0.115975 0.06573,-0.02764 0.130093,-0.05671 0.211632,-0.127682 0.08154,-0.07098 0.221394,-0.233793 0.221394,-0.500185 v -0.156577 c 0,-0.266391 -0.139821,-0.427272 -0.221394,-0.498234 -0.08157,-0.07096 -0.145901,-0.102016 -0.211632,-0.129634 -0.131463,-0.05523 -0.269356,-0.08698 -0.433026,-0.115963 -0.327338,-0.05796 -0.749798,-0.08864 -1.218251,-0.08864 z" 66 + id="path61" 67 + /> 68 + <Path 69 + fill={_fill} 70 + d="m 13.244048,39.692944 c -0.468452,0 -0.889351,0.03068 -1.21669,0.08864 -0.163669,0.02899 -0.301562,0.06074 -0.433025,0.115963 -0.06573,0.02761 -0.130061,0.05867 -0.211633,0.129634 -0.08157,0.07096 -0.221002,0.231843 -0.221002,0.498235 v 0.156576 c 0,0.266392 0.139462,0.429212 0.221002,0.500186 0.08154,0.07098 0.145905,0.100037 0.211633,0.127681 0.131457,0.05529 0.269342,0.08693 0.433025,0.115975 0.327366,0.05808 0.748182,0.09058 1.21669,0.09058 h 1.907032 c -0.185127,-0.59869 -0.320273,-1.207565 -0.400618,-1.823472 z" 71 + id="path60" 72 + /> 73 + <Path 74 + fill={_fill} 75 + d="m 54.517386,33.331095 c -0.288434,0 -0.463159,0.107395 -0.739932,0.249898 -0.276773,0.142496 -0.600065,0.340031 -0.942192,0.575546 l -0.563441,0.387731 c 0.241415,0.550415 0.431989,1.123162 0.566174,1.716876 l 0.762188,-0.524395 c 0.405668,-0.279253 0.757071,-0.55978 1.016381,-0.805139 0.129655,-0.122678 0.235296,-0.233058 0.326039,-0.359229 0.04537,-0.06309 0.08871,-0.126171 0.129634,-0.236231 0.04093,-0.110061 0.09462,-0.333333 -0.01718,-0.564222 l -0.06677,-0.136272 c -0.138132,-0.284601 -0.36175,-0.304563 -0.46895,-0.304563 z" 76 + id="path55" 77 + /> 78 + <Path 79 + fill={_fill} 80 + d="m 13.215544,33.331095 c -0.107302,2.44e-4 -0.3332,0.0238 -0.469339,0.304563 l -0.06677,0.136272 c -0.111806,0.23089 -0.05968,0.454162 -0.01874,0.564222 0.04093,0.110061 0.08622,0.173145 0.131587,0.236231 0.09075,0.126171 0.194431,0.236551 0.324086,0.359229 0.25931,0.245359 0.612667,0.525886 1.018333,0.805139 l 0.769606,0.52947 c 0.138651,-0.58985 0.335293,-1.158459 0.583746,-1.70438 v -3.9e-4 l -0.588821,-0.404912 c -0.34232,-0.235647 -0.666867,-0.43303 -0.943755,-0.575546 -0.276888,-0.142516 -0.450747,-0.250554 -0.739931,-0.249898 z" 81 + id="path52" 82 + /> 83 + <Path 84 + fill={_fill} 85 + d="m 34.094764,28.251437 c -4.933274,0 -9.445323,1.119371 -12.639234,2.985345 -3.193912,1.865974 -4.96476,4.339386 -4.96476,7.151086 0,2.835836 1.76833,5.998454 4.873902,8.447917 3.10557,2.449462 7.477748,4.141309 12.350244,4.141309 4.872496,0 9.325343,-1.692812 12.509438,-4.147035 3.184095,-2.454222 5.018588,-5.625664 5.018588,-8.442191 0,-2.840663 -1.672275,-5.299374 -4.746776,-7.158721 -3.074501,-1.859346 -7.468126,-2.97771 -12.401402,-2.97771 z" 86 + id="path45" 87 + /> 88 + <Path 89 + fill={_fill} 90 + d="m 45.888887,14.9683 c -0.01975,-4.81e-4 -0.03913,2.8e-5 -0.05857,3.91e-4 -0.09592,0.0017 -0.186845,0.005 -0.281525,0.06325 -0.324225,0.199518 -0.657344,0.622035 -0.969525,1.028876 -0.785036,1.023073 -1.590677,2.594779 -2.835558,4.699638 -0.562846,0.951667 -1.547594,3.050937 -2.609088,5.423561 3.239259,0.500131 6.133956,1.490417 8.476999,2.907403 1.428388,0.863838 2.666296,1.909965 3.631326,3.113179 -0.783688,-2.912149 -1.69148,-6.450064 -2.253765,-8.589842 -0.853248,-3.247037 -1.4618,-5.815916 -2.169816,-7.350117 -0.24818,-0.537783 -0.432298,-1.042926 -0.759844,-1.253002 -0.05207,-0.0334 -0.111382,-0.0419 -0.170634,-0.04334 z" 91 + id="path43" 92 + /> 93 + <Path 94 + fill={_fill} 95 + d="m 21.844825,14.9683 c -0.05925,0.0015 -0.118559,0.0099 -0.170634,0.04334 -0.327547,0.210076 -0.511665,0.715218 -0.759846,1.253002 -0.708014,1.534201 -1.316565,4.10308 -2.169814,7.350117 -0.573505,2.182475 -1.506534,5.819634 -2.30062,8.763599 1.028936,-1.280829 2.372768,-2.386873 3.923393,-3.292793 2.317508,-1.353954 5.141324,-2.318786 8.260291,-2.836729 -1.072493,-2.399061 -2.070038,-4.528088 -2.637983,-5.488378 -1.244881,-2.104859 -2.050129,-3.676565 -2.835167,-4.699638 -0.312181,-0.406841 -0.6453,-0.829358 -0.969525,-1.028876 -0.09468,-0.05822 -0.185605,-0.06147 -0.281526,-0.06325 -0.01945,-3.64e-4 -0.03882,-8.72e-4 -0.05856,-3.92e-4 z" 96 + id="path42" 69 97 /> 70 98 </Svg> 71 99 )
+1 -1
src/view/screens/Feeds.tsx
··· 604 604 height: 18, 605 605 }, 606 606 ]} 607 - fill={t.palette.white} 607 + fill={t.palette.black} 608 608 /> 609 609 </View> 610 610 <FeedCard.TitleAndByline
+1 -1
src/view/shell/desktop/LeftNav.tsx
··· 471 471 top: '-10%', 472 472 left: count.length === 1 ? 12 : 8, 473 473 backgroundColor: t.palette.primary_500, 474 - color: t.palette.white, 474 + color: t.palette.black, 475 475 lineHeight: a.text_sm.fontSize, 476 476 paddingHorizontal: 4, 477 477 paddingVertical: 1,