Merge remote-tracking branch 'origin/main' into neue/post-avi
* origin/main: [Neue] Handle emoji within custom font (#5449) Use pressable for video controls (#5452) Resolve source files for fonts, remove hack (#5454) changed white (gray_0) text to offwhite (gray_25) (#5453) Let Expo/Webpack handle CSS assets (#3942)
This commit is contained in:
@@ -21,7 +21,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: '1.22'
|
go-version: '1.22'
|
||||||
- name: Dummy Static Files
|
- name: Dummy Static Files
|
||||||
run: touch bskyweb/static/js/blah.js && touch bskyweb/static/media/blah.txt
|
run: touch bskyweb/static/js/blah.js && touch bskyweb/static/css/blah.txt && touch bskyweb/static/media/blah.txt
|
||||||
- name: Check
|
- name: Check
|
||||||
run: cd bskyweb/ && make check
|
run: cd bskyweb/ && make check
|
||||||
- name: Build (binary)
|
- name: Build (binary)
|
||||||
@@ -38,6 +38,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
go-version: '1.22'
|
go-version: '1.22'
|
||||||
- name: Dummy Static Files
|
- name: Dummy Static Files
|
||||||
run: touch bskyweb/static/js/blah.js && touch bskyweb/static/media/blah.txt
|
run: touch bskyweb/static/js/blah.js && touch bskyweb/static/css/blah.txt && touch bskyweb/static/media/blah.txt
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: cd bskyweb/ && make lint
|
run: cd bskyweb/ && make lint
|
||||||
|
|||||||
+3
-1
@@ -1,4 +1,4 @@
|
|||||||
# Ignore everything except JS-ey code.
|
# Ignore everything except JS-ey or CSS code.
|
||||||
# Based on https://stackoverflow.com/a/70715829/458193
|
# Based on https://stackoverflow.com/a/70715829/458193
|
||||||
*
|
*
|
||||||
!**/*.js
|
!**/*.js
|
||||||
@@ -7,6 +7,8 @@
|
|||||||
!**/*.tsx
|
!**/*.tsx
|
||||||
!*/
|
!*/
|
||||||
|
|
||||||
|
!**/*.css
|
||||||
|
|
||||||
# More specific ignores go below.
|
# More specific ignores go below.
|
||||||
.expo
|
.expo
|
||||||
android
|
android
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ RUN find ./bskyweb/embedr-static && find ./bskyweb/embedr-templates && find ./bs
|
|||||||
|
|
||||||
# hack around issue with empty directory and go:embed
|
# hack around issue with empty directory and go:embed
|
||||||
RUN touch bskyweb/static/js/empty.txt
|
RUN touch bskyweb/static/js/empty.txt
|
||||||
|
RUN touch bskyweb/static/css/empty.txt
|
||||||
RUN touch bskyweb/static/media/empty.txt
|
RUN touch bskyweb/static/media/empty.txt
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -4,4 +4,4 @@
|
|||||||
|
|
||||||
.break-word {
|
.break-word {
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ static/js/*.js
|
|||||||
static/js/*.map
|
static/js/*.map
|
||||||
static/js/*.js.LICENSE.txt
|
static/js/*.js.LICENSE.txt
|
||||||
static/js/empty.txt
|
static/js/empty.txt
|
||||||
|
static/css/*.css
|
||||||
|
static/css/*.map
|
||||||
|
static/css/*.css.LICENSE.txt
|
||||||
|
static/css/empty.txt
|
||||||
static/media/*.png
|
static/media/*.png
|
||||||
static/media/empty.txt
|
static/media/empty.txt
|
||||||
templates/scripts.html
|
templates/scripts.html
|
||||||
|
|||||||
@@ -32,387 +32,6 @@
|
|||||||
<link rel="preload" as="font" type="font/otf" href="/static/media/Inter-BlackItalic.27b9f0ad06fd13a7b9da.otf">
|
<link rel="preload" as="font" type="font/otf" href="/static/media/Inter-BlackItalic.27b9f0ad06fd13a7b9da.otf">
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<style>
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-Regular";
|
|
||||||
src: local("Inter-Regular"), url(/static/media/Inter-Regular.1f5ed03b6dd9fd1f9982.otf) format("font/otf");
|
|
||||||
font-weight: 400;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-Italic";
|
|
||||||
src: local("Inter-Italic"), url(/static/media/Inter-Italic.95778eb0c75dc956257e.otf) format("font/otf");
|
|
||||||
font-weight: 400;
|
|
||||||
font-style: italic;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-Medium";
|
|
||||||
src: local("Inter-Medium"), url(/static/media/Inter-Medium.296aa2d65964269836b3.otf) format("font/otf");
|
|
||||||
font-weight: 500;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-MediumItalic";
|
|
||||||
src: local("Inter-MediumItalic"), url(/static/media/Inter-MediumItalic.0e57e17a6311368e2114.otf) format("font/otf");
|
|
||||||
font-weight: 500;
|
|
||||||
font-style: italic;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-SemiBold";
|
|
||||||
src: local("Inter-SemiBold"), url(/static/media/Inter-SemiBold.2277990330981b8409bb.otf) format("font/otf");
|
|
||||||
font-weight: 600;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-SemiBoldItalic";
|
|
||||||
src: local("Inter-SemiBoldItalic"), url(/static/media/Inter-SemiBoldItalic.f62fea3df3a521d6c8a7.otf) format("font/otf");
|
|
||||||
font-weight: 600;
|
|
||||||
font-style: italic;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-Bold";
|
|
||||||
src: local("Inter-Bold"), url(/static/media/Inter-Bold.8d330503e1d034ad68de.otf) format("font/otf");
|
|
||||||
font-weight: 700;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-BoldItalic";
|
|
||||||
src: local("Inter-BoldItalic"), url(/static/media/Inter-BoldItalic.bb17e63f9baa0d861a20.otf) format("font/otf");
|
|
||||||
font-weight: 700;
|
|
||||||
font-style: italic;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-ExtraBold";
|
|
||||||
src: local("Inter-ExtraBold"), url(/static/media/Inter-ExtraBold.ff2581a193bf6b7e0b06.otf) format("font/otf");
|
|
||||||
font-weight: 800;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-ExtraBoldItalic";
|
|
||||||
src: local("Inter-ExtraBoldItalic"), url(/static/media/Inter-ExtraBoldItalic.0e50b40728d24d40fdf4.otf) format("font/otf");
|
|
||||||
font-weight: 800;
|
|
||||||
font-style: italic;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-Black";
|
|
||||||
src: local("Inter-Black"), url(/static/media/Inter-Black.66e9a87f1c921e844ed4.otf) format("font/otf");
|
|
||||||
font-weight: 900;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-BlackItalic";
|
|
||||||
src: local("Inter-BlackItalic"), url(/static/media/Inter-BlackItalic.27b9f0ad06fd13a7b9da.otf) format("font/otf");
|
|
||||||
font-weight: 900;
|
|
||||||
font-style: italic;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extend the react-native-web reset:
|
|
||||||
* https://github.com/necolas/react-native-web/blob/master/packages/react-native-web/src/exports/StyleSheet/initialRules.js
|
|
||||||
*/
|
|
||||||
html,
|
|
||||||
body,
|
|
||||||
#root {
|
|
||||||
width: 100%;
|
|
||||||
/* To smooth any scrolling behavior */
|
|
||||||
-webkit-overflow-scrolling: touch;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
/* Allows content to fill the viewport and go beyond the bottom */
|
|
||||||
min-height: 100%;
|
|
||||||
}
|
|
||||||
#root {
|
|
||||||
flex-shrink: 0;
|
|
||||||
flex-basis: auto;
|
|
||||||
flex-grow: 1;
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
|
||||||
/* Prevent text size change on orientation change https://gist.github.com/tfausak/2222823#file-ios-8-web-app-html-L138 */
|
|
||||||
-webkit-text-size-adjust: 100%;
|
|
||||||
height: calc(100% + env(safe-area-inset-top));
|
|
||||||
scrollbar-gutter: stable both-edges;
|
|
||||||
}
|
|
||||||
html, body {
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Liberation Sans", Helvetica, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
#preload {
|
|
||||||
width: 100px;
|
|
||||||
position: fixed;
|
|
||||||
left: 50%;
|
|
||||||
top: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Buttons and inputs have a font set by UA, so we'll have to reset that */
|
|
||||||
button, input, textarea {
|
|
||||||
font: inherit;
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Color theming */
|
|
||||||
/* Default will always be white */
|
|
||||||
:root {
|
|
||||||
--text: black;
|
|
||||||
--background: white;
|
|
||||||
--backgroundLight: hsl(211, 20%, 95%);
|
|
||||||
}
|
|
||||||
/* This gives us a black background when system is dark and we have not loaded the theme/color scheme values in JS */
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
:root {
|
|
||||||
--text: white;
|
|
||||||
--background: black;
|
|
||||||
--backgroundLight: hsl(211, 20%, 20%);
|
|
||||||
color-scheme: dark;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Overwrite those preferences with the selected theme */
|
|
||||||
html.theme--light {
|
|
||||||
--text: black;
|
|
||||||
--background: white;
|
|
||||||
--backgroundLight: hsl(211, 20%, 95%);
|
|
||||||
}
|
|
||||||
html.theme--dark {
|
|
||||||
--text: white;
|
|
||||||
--background: black;
|
|
||||||
--backgroundLight: hsl(211, 20%, 20%);
|
|
||||||
color-scheme: dark;
|
|
||||||
}
|
|
||||||
html.theme--dim {
|
|
||||||
--text: white;
|
|
||||||
--background: hsl(211, 20%, 4%);
|
|
||||||
--backgroundLight: hsl(211, 20%, 10%);
|
|
||||||
color-scheme: dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove autofill styles on Webkit */
|
|
||||||
input:autofill,
|
|
||||||
input:-webkit-autofill,
|
|
||||||
input:-webkit-autofill:hover,
|
|
||||||
input:-webkit-autofill:focus,
|
|
||||||
input:-webkit-autofill:active{
|
|
||||||
-webkit-background-clip: text;
|
|
||||||
-webkit-text-fill-color: var(--text);
|
|
||||||
transition: background-color 5000s ease-in-out 0s;
|
|
||||||
box-shadow: inset 0 0 20px 20px var(--background);
|
|
||||||
background: var(--background);
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
/* Force left-align date/time inputs on iOS mobile */
|
|
||||||
input::-webkit-date-and-time-value {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
display: flex;
|
|
||||||
/* Allows you to scroll below the viewport; default value is visible */
|
|
||||||
overflow-y: auto;
|
|
||||||
overscroll-behavior-y: none;
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
background-color: var(--background);
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
-ms-overflow-style: scrollbar;
|
|
||||||
font-synthesis-weight: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove default link styling */
|
|
||||||
a {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
a[role="link"]:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
a[role="link"][data-no-underline="1"]:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Styling hacks */
|
|
||||||
*[data-word-wrap] {
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
*[data-stable-gutters] {
|
|
||||||
scrollbar-gutter: stable both-edges;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ProseMirror */
|
|
||||||
.ProseMirror {
|
|
||||||
min-height: 140px;
|
|
||||||
}
|
|
||||||
.ProseMirror-dark {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.ProseMirror p {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.ProseMirror p.is-editor-empty:first-child::before {
|
|
||||||
color: #8d8e96;
|
|
||||||
content: attr(data-placeholder);
|
|
||||||
float: left;
|
|
||||||
height: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.ProseMirror .mention {
|
|
||||||
color: #0085ff;
|
|
||||||
}
|
|
||||||
.ProseMirror a,
|
|
||||||
.ProseMirror .autolink {
|
|
||||||
color: #0085ff;
|
|
||||||
}
|
|
||||||
/* OLLIE: TODO -- this is not accessible */
|
|
||||||
/* Remove focus state on inputs */
|
|
||||||
.ProseMirror-focused {
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
textarea:focus,
|
|
||||||
input:focus {
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
.tippy-content .items {
|
|
||||||
width: fit-content;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tooltips */
|
|
||||||
[data-tooltip] {
|
|
||||||
position: relative;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
[data-tooltip]::after {
|
|
||||||
content: attr(data-tooltip);
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateY(100%) translateY(8px) translateX(-50%);
|
|
||||||
padding: 4px 10px;
|
|
||||||
border-radius: 10px;
|
|
||||||
background: var(--backgroundLight);
|
|
||||||
color: var(--text);
|
|
||||||
text-align: center;
|
|
||||||
white-space: nowrap;
|
|
||||||
font-size: 12px;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
[data-tooltip]::before {
|
|
||||||
content: '';
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
border-bottom: 6px solid var(--backgroundLight);
|
|
||||||
border-left: 6px solid transparent;
|
|
||||||
border-right: 6px solid transparent;
|
|
||||||
bottom: 0;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateY(100%) translateY(2px) translateX(-50%);
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
[data-tooltip]:hover::after,
|
|
||||||
[data-tooltip]:hover::before {
|
|
||||||
display:block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NativeDropdown component */
|
|
||||||
.radix-dropdown-item:focus,
|
|
||||||
.nativeDropdown-item:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Spinner component */
|
|
||||||
@keyframes rotate {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.rotate-500ms {
|
|
||||||
position: absolute;
|
|
||||||
inset:0;
|
|
||||||
animation: rotate 500ms linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes avatarHoverFadeIn {
|
|
||||||
from { opacity: 0; }
|
|
||||||
to { opacity: 1; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes avatarHoverFadeOut {
|
|
||||||
from { opacity: 1; }
|
|
||||||
to { opacity: 0; }
|
|
||||||
}
|
|
||||||
|
|
||||||
.force-no-clicks > *,
|
|
||||||
.force-no-clicks * {
|
|
||||||
pointer-events: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=range][orient=vertical] {
|
|
||||||
writing-mode: vertical-lr;
|
|
||||||
direction: rtl;
|
|
||||||
appearance: slider-vertical;
|
|
||||||
width: 16px;
|
|
||||||
vertical-align: bottom;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
appearance: none;
|
|
||||||
background: transparent;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="range"][orient=vertical]::-webkit-slider-runnable-track {
|
|
||||||
background: white;
|
|
||||||
height: 100%;
|
|
||||||
width: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="range"][orient=vertical]::-moz-range-track {
|
|
||||||
background: white;
|
|
||||||
height: 100%;
|
|
||||||
width: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="range"]::-webkit-slider-thumb {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
appearance: none;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: white;
|
|
||||||
height: 16px;
|
|
||||||
width: 16px;
|
|
||||||
margin-left: -6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="range"][orient=vertical]::-moz-range-thumb {
|
|
||||||
border: none;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: white;
|
|
||||||
height: 16px;
|
|
||||||
width: 16px;
|
|
||||||
margin-left: -6px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% include "scripts.html" %}
|
{% include "scripts.html" %}
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||||
|
|||||||
+4
-2
@@ -15,7 +15,7 @@
|
|||||||
"web": "expo start --web",
|
"web": "expo start --web",
|
||||||
"use-build-number": "./scripts/useBuildNumberEnv.sh",
|
"use-build-number": "./scripts/useBuildNumberEnv.sh",
|
||||||
"use-build-number-with-bump": "./scripts/useBuildNumberEnvWithBump.sh",
|
"use-build-number-with-bump": "./scripts/useBuildNumberEnvWithBump.sh",
|
||||||
"build-web": "expo export:web && node ./scripts/post-web-build.js && cp -v ./web-build/static/js/*.* ./bskyweb/static/js/ && cp -v ./web-build/static/media/* ./bskyweb/static/media/",
|
"build-web": "expo export:web && node ./scripts/post-web-build.js",
|
||||||
"build-all": "yarn intl:build && yarn use-build-number-with-bump eas build --platform all",
|
"build-all": "yarn intl:build && yarn use-build-number-with-bump eas build --platform all",
|
||||||
"build-ios": "yarn use-build-number-with-bump eas build -p ios",
|
"build-ios": "yarn use-build-number-with-bump eas build -p ios",
|
||||||
"build-android": "yarn use-build-number-with-bump eas build -p android",
|
"build-android": "yarn use-build-number-with-bump eas build -p android",
|
||||||
@@ -339,7 +339,9 @@
|
|||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*{.js,.jsx,.ts,.tsx}": [
|
"*{.js,.jsx,.ts,.tsx}": [
|
||||||
"eslint --cache --fix",
|
"eslint --cache --fix"
|
||||||
|
],
|
||||||
|
"*{.js,.jsx,.ts,.tsx,.css}": [
|
||||||
"prettier --cache --write --ignore-unknown"
|
"prettier --cache --write --ignore-unknown"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,30 @@ console.log(`Writing ${templateFile}`)
|
|||||||
const outputFile = entrypoints
|
const outputFile = entrypoints
|
||||||
.map(name => {
|
.map(name => {
|
||||||
const file = path.basename(name)
|
const file = path.basename(name)
|
||||||
return `<script defer="defer" src="/static/js/${file}"></script>`
|
const ext = path.extname(file)
|
||||||
|
|
||||||
|
if (ext === '.js') {
|
||||||
|
return `<script defer="defer" src="/static/js/${file}"></script>`
|
||||||
|
}
|
||||||
|
if (ext === '.css') {
|
||||||
|
return `<link rel="stylesheet" href="/static/css/${file}">`
|
||||||
|
}
|
||||||
|
|
||||||
|
return ''
|
||||||
})
|
})
|
||||||
.join('\n')
|
.join('\n')
|
||||||
fs.writeFileSync(templateFile, outputFile)
|
fs.writeFileSync(templateFile, outputFile)
|
||||||
|
|
||||||
|
function copyFiles(sourceDir, targetDir) {
|
||||||
|
const files = fs.readdirSync(path.join(projectRoot, sourceDir))
|
||||||
|
files.forEach(file => {
|
||||||
|
const sourcePath = path.join(projectRoot, sourceDir, file)
|
||||||
|
const targetPath = path.join(projectRoot, targetDir, file)
|
||||||
|
fs.copyFileSync(sourcePath, targetPath)
|
||||||
|
console.log(`Copied ${sourcePath} to ${targetPath}`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
copyFiles('web-build/static/js', 'bskyweb/static/js')
|
||||||
|
copyFiles('web-build/static/css', 'bskyweb/static/css')
|
||||||
|
copyFiles('web-build/static/media', 'bskyweb/static/media')
|
||||||
|
|||||||
+3
-2
@@ -1,5 +1,6 @@
|
|||||||
import 'lib/sentry' // must be near top
|
import '#/lib/sentry' // must be near top
|
||||||
import 'view/icons'
|
import '#/view/icons'
|
||||||
|
import './style.css'
|
||||||
|
|
||||||
import React, {useEffect, useState} from 'react'
|
import React, {useEffect, useState} from 'react'
|
||||||
import {KeyboardProvider} from 'react-native-keyboard-controller'
|
import {KeyboardProvider} from 'react-native-keyboard-controller'
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import {useFonts as defaultUseFonts} from 'expo-font'
|
|
||||||
|
|
||||||
import {isWeb} from '#/platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
import {Device, device} from '#/storage'
|
import {Device, device} from '#/storage'
|
||||||
|
|
||||||
@@ -34,39 +32,6 @@ export function setFontFamily(fontFamily: Device['fontFamily']) {
|
|||||||
device.set(['fontFamily'], fontFamily)
|
device.set(['fontFamily'], fontFamily)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* IMPORTANT: This is unused. Expo statically extracts these fonts, but we load
|
|
||||||
* them manually so that we can parallelize the loading along with the JS
|
|
||||||
* bundle.
|
|
||||||
*
|
|
||||||
* See `#/alf/util/useFonts` for the actually used hooks.
|
|
||||||
*
|
|
||||||
* All used fonts MUST be configured here. Unused fonts are commented out, but
|
|
||||||
* the files are there if we need them.
|
|
||||||
*/
|
|
||||||
export function DO_NOT_USE() {
|
|
||||||
return defaultUseFonts({
|
|
||||||
// 'Inter-Thin': require('../../assets/fonts/inter/Inter-Thin.otf'),
|
|
||||||
// 'Inter-ThinItalic': require('../../assets/fonts/inter/Inter-ThinItalic.otf'),
|
|
||||||
// 'Inter-ExtraLight': require('../../assets/fonts/inter/Inter-ExtraLight.otf'),
|
|
||||||
// 'Inter-ExtraLightItalic': require('../../assets/fonts/inter/Inter-ExtraLightItalic.otf'),
|
|
||||||
// 'Inter-Light': require('../../assets/fonts/inter/Inter-Light.otf'),
|
|
||||||
// 'Inter-LightItalic': require('../../assets/fonts/inter/Inter-LightItalic.otf'),
|
|
||||||
'Inter-Regular': require('../../assets/fonts/inter/Inter-Regular.otf'),
|
|
||||||
'Inter-Italic': require('../../assets/fonts/inter/Inter-Italic.otf'),
|
|
||||||
// 'Inter-Medium': require('../../assets/fonts/inter/Inter-Medium.otf'),
|
|
||||||
// 'Inter-MediumItalic': require('../../assets/fonts/inter/Inter-MediumItalic.otf'),
|
|
||||||
'Inter-SemiBold': require('../../assets/fonts/inter/Inter-SemiBold.otf'),
|
|
||||||
'Inter-SemiBoldItalic': require('../../assets/fonts/inter/Inter-SemiBoldItalic.otf'),
|
|
||||||
// 'Inter-Bold': require('../../assets/fonts/inter/Inter-Bold.otf'),
|
|
||||||
// 'Inter-BoldItalic': require('../../assets/fonts/inter/Inter-BoldItalic.otf'),
|
|
||||||
'Inter-ExtraBold': require('../../assets/fonts/inter/Inter-ExtraBold.otf'),
|
|
||||||
'Inter-ExtraBoldItalic': require('../../assets/fonts/inter/Inter-ExtraBoldItalic.otf'),
|
|
||||||
// 'Inter-Black': require('../../assets/fonts/inter/Inter-Black.otf'),
|
|
||||||
// 'Inter-BlackItalic': require('../../assets/fonts/inter/Inter-BlackItalic.otf'),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unused fonts are commented out, but the files are there if we need them.
|
* Unused fonts are commented out, but the files are there if we need them.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+1
-1
@@ -183,7 +183,7 @@ export function createThemes({
|
|||||||
} as const
|
} as const
|
||||||
|
|
||||||
const darkPalette: Palette = {
|
const darkPalette: Palette = {
|
||||||
white: color.gray_0,
|
white: color.gray_25,
|
||||||
black: color.trueBlack,
|
black: color.trueBlack,
|
||||||
|
|
||||||
contrast_25: color.gray_975,
|
contrast_25: color.gray_975,
|
||||||
|
|||||||
@@ -52,13 +52,14 @@ export function Title({value}: {value: string}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function Description({value, handle}: {value?: string; handle: string}) {
|
export function Description({value, handle}: {value?: string; handle: string}) {
|
||||||
|
const {_} = useLingui()
|
||||||
return value ? (
|
return value ? (
|
||||||
<Text numberOfLines={2}>
|
<Text numberOfLines={2}>
|
||||||
<RichText value={value} style={[a.leading_snug]} />
|
<RichText value={value} style={[a.leading_snug]} />
|
||||||
</Text>
|
</Text>
|
||||||
) : (
|
) : (
|
||||||
<Text style={[a.leading_snug]}>
|
<Text emoji style={[a.leading_snug]}>
|
||||||
<Trans>By {sanitizeHandle(handle, '@')}</Trans>
|
{_(msg`By ${sanitizeHandle(handle, '@')}`)}
|
||||||
</Text>
|
</Text>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ import {
|
|||||||
moderateUserList,
|
moderateUserList,
|
||||||
ModerationUI,
|
ModerationUI,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
|
import {useLingui} from '@lingui/react'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
@@ -111,6 +112,7 @@ export function TitleAndByline({
|
|||||||
modUi?: ModerationUI
|
modUi?: ModerationUI
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
const {_} = useLingui()
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -140,15 +142,12 @@ export function TitleAndByline({
|
|||||||
|
|
||||||
{creator && (
|
{creator && (
|
||||||
<Text
|
<Text
|
||||||
|
emoji
|
||||||
style={[a.leading_snug, t.atoms.text_contrast_medium]}
|
style={[a.leading_snug, t.atoms.text_contrast_medium]}
|
||||||
numberOfLines={1}>
|
numberOfLines={1}>
|
||||||
{purpose === MODLIST ? (
|
{purpose === MODLIST
|
||||||
<Trans>
|
? _(msg`Moderation list by ${sanitizeHandle(creator.handle, '@')}`)
|
||||||
Moderation list by {sanitizeHandle(creator.handle, '@')}
|
: _(msg`List by ${sanitizeHandle(creator.handle, '@')}`)}
|
||||||
</Trans>
|
|
||||||
) : (
|
|
||||||
<Trans>List by {sanitizeHandle(creator.handle, '@')}</Trans>
|
|
||||||
)}
|
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -181,6 +181,7 @@ export function NameAndHandle({
|
|||||||
{name}
|
{name}
|
||||||
</Text>
|
</Text>
|
||||||
<Text
|
<Text
|
||||||
|
emoji
|
||||||
style={[a.leading_snug, t.atoms.text_contrast_medium]}
|
style={[a.leading_snug, t.atoms.text_contrast_medium]}
|
||||||
numberOfLines={1}>
|
numberOfLines={1}>
|
||||||
{handle}
|
{handle}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react'
|
|||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {AppBskyGraphDefs, AppBskyGraphStarterpack, AtUri} from '@atproto/api'
|
import {AppBskyGraphDefs, AppBskyGraphStarterpack, AtUri} from '@atproto/api'
|
||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
@@ -69,13 +69,10 @@ export function Card({
|
|||||||
<Text emoji style={[a.text_md, a.font_bold, a.leading_snug]}>
|
<Text emoji style={[a.text_md, a.font_bold, a.leading_snug]}>
|
||||||
{record.name}
|
{record.name}
|
||||||
</Text>
|
</Text>
|
||||||
<Text style={[a.leading_snug, t.atoms.text_contrast_medium]}>
|
<Text emoji style={[a.leading_snug, t.atoms.text_contrast_medium]}>
|
||||||
<Trans>
|
{creator?.did === currentAccount?.did
|
||||||
Starter pack by{' '}
|
? _(msg`Starter pack by you`)
|
||||||
{creator?.did === currentAccount?.did
|
: _(msg`Starter pack by ${sanitizeHandle(creator.handle, '@')}`)}
|
||||||
? _(msg`you`)
|
|
||||||
: `@${sanitizeHandle(creator.handle)}`}
|
|
||||||
</Trans>
|
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -159,9 +159,7 @@ export function Text({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (emoji && !childIsString(children)) {
|
if (emoji && !childIsString(children)) {
|
||||||
throw new Error(
|
logger.error('Text: when <Text emoji />, children can only be strings.')
|
||||||
'Text: when <Text emoji />, children can only be strings.',
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -325,11 +325,11 @@ export const darkTheme: Theme = {
|
|||||||
textInverted: colors.green2,
|
textInverted: colors.green2,
|
||||||
},
|
},
|
||||||
inverted: {
|
inverted: {
|
||||||
background: lightPalette.white,
|
background: darkPalette.white,
|
||||||
backgroundLight: lightPalette.contrast_50,
|
backgroundLight: lightPalette.contrast_50,
|
||||||
text: lightPalette.black,
|
text: lightPalette.black,
|
||||||
textLight: lightPalette.contrast_700,
|
textLight: lightPalette.contrast_700,
|
||||||
textInverted: lightPalette.white,
|
textInverted: darkPalette.white,
|
||||||
link: lightPalette.primary_500,
|
link: lightPalette.primary_500,
|
||||||
border: lightPalette.contrast_100,
|
border: lightPalette.contrast_100,
|
||||||
borderDark: lightPalette.contrast_200,
|
borderDark: lightPalette.contrast_200,
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {AppBskyActorDefs} from '@atproto/api'
|
import {AppBskyActorDefs} from '@atproto/api'
|
||||||
import {Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
|
import {isInvalidHandle} from '#/lib/strings/handles'
|
||||||
|
import {isIOS} from '#/platform/detection'
|
||||||
import {Shadow} from '#/state/cache/types'
|
import {Shadow} from '#/state/cache/types'
|
||||||
import {isInvalidHandle} from 'lib/strings/handles'
|
|
||||||
import {isIOS} from 'platform/detection'
|
|
||||||
import {atoms as a, useTheme, web} from '#/alf'
|
import {atoms as a, useTheme, web} from '#/alf'
|
||||||
import {NewskieDialog} from '#/components/NewskieDialog'
|
import {NewskieDialog} from '#/components/NewskieDialog'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
@@ -18,6 +19,7 @@ export function ProfileHeaderHandle({
|
|||||||
disableTaps?: boolean
|
disableTaps?: boolean
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
const {_} = useLingui()
|
||||||
const invalidHandle = isInvalidHandle(profile.handle)
|
const invalidHandle = isInvalidHandle(profile.handle)
|
||||||
const blockHide = profile.viewer?.blocking || profile.viewer?.blockedBy
|
const blockHide = profile.viewer?.blocking || profile.viewer?.blockedBy
|
||||||
return (
|
return (
|
||||||
@@ -33,6 +35,7 @@ export function ProfileHeaderHandle({
|
|||||||
</View>
|
</View>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
<Text
|
<Text
|
||||||
|
emoji
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
style={[
|
style={[
|
||||||
invalidHandle
|
invalidHandle
|
||||||
@@ -47,7 +50,7 @@ export function ProfileHeaderHandle({
|
|||||||
: [a.text_md, a.leading_tight, t.atoms.text_contrast_medium],
|
: [a.text_md, a.leading_tight, t.atoms.text_contrast_medium],
|
||||||
web({wordBreak: 'break-all'}),
|
web({wordBreak: 'break-all'}),
|
||||||
]}>
|
]}>
|
||||||
{invalidHandle ? <Trans>⚠Invalid Handle</Trans> : `@${profile.handle}`}
|
{invalidHandle ? _(msg`⚠Invalid Handle`) : `@${profile.handle}`}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
|||||||
+399
@@ -0,0 +1,399 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Inter-Regular';
|
||||||
|
src: local('Inter-Regular'),
|
||||||
|
url(/assets/fonts/inter/Inter-Regular.otf) format('font/otf');
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Inter-Italic';
|
||||||
|
src: local('Inter-Italic'),
|
||||||
|
url(/assets/fonts/inter/Inter-Italic.otf) format('font/otf');
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter-Medium";
|
||||||
|
src: local("Inter-Medium"), url(/assets/fonts/inter/Inter-Medium.otf) format("font/otf");
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter-MediumItalic";
|
||||||
|
src: local("Inter-MediumItalic"), url(/assets/fonts/inter/Inter-MediumItalic.otf) format("font/otf");
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Inter-SemiBold';
|
||||||
|
src: local('Inter-SemiBold'),
|
||||||
|
url(/assets/fonts/inter/Inter-SemiBold.otf) format('font/otf');
|
||||||
|
font-weight: 600;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Inter-SemiBoldItalic';
|
||||||
|
src: local('Inter-SemiBoldItalic'),
|
||||||
|
url(/assets/fonts/inter/Inter-SemiBoldItalic.otf) format('font/otf');
|
||||||
|
font-weight: 600;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter-Bold";
|
||||||
|
src: local("Inter-Bold"), url(/assets/fonts/inter/Inter-Bold.otf) format("font/otf");
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter-BoldItalic";
|
||||||
|
src: local("Inter-BoldItalic"), url(/assets/fonts/inter/Inter-BoldItalic.otf) format("font/otf");
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Inter-ExtraBold';
|
||||||
|
src: local('Inter-ExtraBold'),
|
||||||
|
url(/assets/fonts/inter/Inter-ExtraBold.otf) format('font/otf');
|
||||||
|
font-weight: 800;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Inter-ExtraBoldItalic';
|
||||||
|
src: local('Inter-ExtraBoldItalic'),
|
||||||
|
url(/assets/fonts/inter/Inter-ExtraBoldItalic.otf) format('font/otf');
|
||||||
|
font-weight: 800;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter-Black";
|
||||||
|
src: local("Inter-Black"), url(/assets/fonts/inter/Inter-Black.otf) format("font/otf");
|
||||||
|
font-weight: 900;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: "Inter-BlackItalic";
|
||||||
|
src: local("Inter-BlackItalic"), url(/assets/fonts/inter/Inter-BlackItalic.otf) format("font/otf");
|
||||||
|
font-weight: 900;
|
||||||
|
font-style: italic;
|
||||||
|
font-display: swap;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extend the react-native-web reset:
|
||||||
|
* https://github.com/necolas/react-native-web/blob/master/packages/react-native-web/src/exports/StyleSheet/initialRules.js
|
||||||
|
*/
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
#root {
|
||||||
|
width: 100%;
|
||||||
|
/* To smooth any scrolling behavior */
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
/* Allows content to fill the viewport and go beyond the bottom */
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
#root {
|
||||||
|
flex-shrink: 0;
|
||||||
|
flex-basis: auto;
|
||||||
|
flex-grow: 1;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
/* Prevent text size change on orientation change https://gist.github.com/tfausak/2222823#file-ios-8-web-app-html-L138 */
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
height: calc(100% + env(safe-area-inset-top));
|
||||||
|
scrollbar-gutter: stable both-edges;
|
||||||
|
}
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
||||||
|
'Liberation Sans', Helvetica, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
#preload {
|
||||||
|
width: 100px;
|
||||||
|
position: fixed;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buttons and inputs have a font set by UA, so we'll have to reset that */
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
textarea {
|
||||||
|
font: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Color theming */
|
||||||
|
/* Default will always be white */
|
||||||
|
:root {
|
||||||
|
--text: black;
|
||||||
|
--background: white;
|
||||||
|
--backgroundLight: hsl(211, 20%, 95%);
|
||||||
|
}
|
||||||
|
/* This gives us a black background when system is dark and we have not loaded the theme/color scheme values in JS */
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--text: white;
|
||||||
|
--background: black;
|
||||||
|
--backgroundLight: hsl(211, 20%, 20%);
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Overwrite those preferences with the selected theme */
|
||||||
|
html.theme--light {
|
||||||
|
--text: black;
|
||||||
|
--background: white;
|
||||||
|
--backgroundLight: hsl(211, 20%, 95%);
|
||||||
|
}
|
||||||
|
html.theme--dark {
|
||||||
|
--text: white;
|
||||||
|
--background: black;
|
||||||
|
--backgroundLight: hsl(211, 20%, 20%);
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
html.theme--dim {
|
||||||
|
--text: white;
|
||||||
|
--background: hsl(211, 20%, 4%);
|
||||||
|
--backgroundLight: hsl(211, 20%, 10%);
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove autofill styles on Webkit */
|
||||||
|
input:autofill,
|
||||||
|
input:-webkit-autofill,
|
||||||
|
input:-webkit-autofill:hover,
|
||||||
|
input:-webkit-autofill:focus,
|
||||||
|
input:-webkit-autofill:active {
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: var(--text);
|
||||||
|
transition: background-color 5000s ease-in-out 0s;
|
||||||
|
box-shadow: inset 0 0 20px 20px var(--background);
|
||||||
|
background: var(--background);
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
/* Force left-align date/time inputs on iOS mobile */
|
||||||
|
input::-webkit-date-and-time-value {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
/* Allows you to scroll below the viewport; default value is visible */
|
||||||
|
overflow-y: auto;
|
||||||
|
overscroll-behavior-y: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
background-color: var(--background);
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
-ms-overflow-style: scrollbar;
|
||||||
|
font-synthesis-weight: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove default link styling */
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
a[role='link']:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
a[role='link'][data-no-underline='1']:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Styling hacks */
|
||||||
|
*[data-word-wrap] {
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
*[data-stable-gutters] {
|
||||||
|
scrollbar-gutter: stable both-edges;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ProseMirror */
|
||||||
|
.ProseMirror {
|
||||||
|
font: 18px -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
||||||
|
'Liberation Sans', Helvetica, Arial, sans-serif;
|
||||||
|
min-height: 140px;
|
||||||
|
}
|
||||||
|
.ProseMirror-dark {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.ProseMirror p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.ProseMirror p.is-editor-empty:first-child::before {
|
||||||
|
color: #8d8e96;
|
||||||
|
content: attr(data-placeholder);
|
||||||
|
float: left;
|
||||||
|
height: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.ProseMirror .mention {
|
||||||
|
color: #0085ff;
|
||||||
|
}
|
||||||
|
.ProseMirror a,
|
||||||
|
.ProseMirror .autolink {
|
||||||
|
color: #0085ff;
|
||||||
|
}
|
||||||
|
/* OLLIE: TODO -- this is not accessible */
|
||||||
|
/* Remove focus state on inputs */
|
||||||
|
.ProseMirror-focused {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
textarea:focus,
|
||||||
|
input:focus {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
.tippy-content .items {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tooltips */
|
||||||
|
[data-tooltip] {
|
||||||
|
position: relative;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
[data-tooltip]::after {
|
||||||
|
content: attr(data-tooltip);
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateY(100%) translateY(8px) translateX(-50%);
|
||||||
|
padding: 4px 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: var(--backgroundLight);
|
||||||
|
color: var(--text);
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 12px;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
[data-tooltip]::before {
|
||||||
|
content: '';
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
border-bottom: 6px solid var(--backgroundLight);
|
||||||
|
border-left: 6px solid transparent;
|
||||||
|
border-right: 6px solid transparent;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateY(100%) translateY(2px) translateX(-50%);
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
[data-tooltip]:hover::after,
|
||||||
|
[data-tooltip]:hover::before {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NativeDropdown component */
|
||||||
|
.radix-dropdown-item:focus,
|
||||||
|
.nativeDropdown-item:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spinner component */
|
||||||
|
@keyframes rotate {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.rotate-500ms {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
animation: rotate 500ms linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes avatarHoverFadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes avatarHoverFadeOut {
|
||||||
|
from {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.force-no-clicks > *,
|
||||||
|
.force-no-clicks * {
|
||||||
|
pointer-events: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='range'][orient='vertical'] {
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
direction: rtl;
|
||||||
|
appearance: slider-vertical;
|
||||||
|
width: 16px;
|
||||||
|
vertical-align: bottom;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
background: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='range'][orient='vertical']::-webkit-slider-runnable-track {
|
||||||
|
background: white;
|
||||||
|
height: 100%;
|
||||||
|
width: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='range'][orient='vertical']::-moz-range-track {
|
||||||
|
background: white;
|
||||||
|
height: 100%;
|
||||||
|
width: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='range']::-webkit-slider-thumb {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: white;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
margin-left: -6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='range'][orient='vertical']::-moz-range-thumb {
|
||||||
|
border: none;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: white;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
margin-left: -6px;
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'
|
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'
|
||||||
import {LayoutChangeEvent, ScrollView, StyleSheet, View} from 'react-native'
|
import {LayoutChangeEvent, ScrollView, StyleSheet, View} from 'react-native'
|
||||||
|
|
||||||
|
import {usePalette} from '#/lib/hooks/usePalette'
|
||||||
|
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||||
import {isNative} from '#/platform/detection'
|
import {isNative} from '#/platform/detection'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
|
||||||
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
|
|
||||||
import {PressableWithHover} from '../util/PressableWithHover'
|
import {PressableWithHover} from '../util/PressableWithHover'
|
||||||
import {Text} from '../util/text/Text'
|
import {Text} from '../util/text/Text'
|
||||||
import {DraggableScrollView} from './DraggableScrollView'
|
import {DraggableScrollView} from './DraggableScrollView'
|
||||||
@@ -131,13 +131,14 @@ export function TabBar({
|
|||||||
<PressableWithHover
|
<PressableWithHover
|
||||||
testID={`${testID}-selector-${i}`}
|
testID={`${testID}-selector-${i}`}
|
||||||
key={`${item}-${i}`}
|
key={`${item}-${i}`}
|
||||||
ref={node => (itemRefs.current[i] = node)}
|
ref={node => (itemRefs.current[i] = node as any)}
|
||||||
onLayout={e => onItemLayout(e, i)}
|
onLayout={e => onItemLayout(e, i)}
|
||||||
style={styles.item}
|
style={styles.item}
|
||||||
hoverStyle={pal.viewLight}
|
hoverStyle={pal.viewLight}
|
||||||
onPress={() => onPressItem(i)}>
|
onPress={() => onPressItem(i)}>
|
||||||
<View style={[styles.itemInner, selected && indicatorStyle]}>
|
<View style={[styles.itemInner, selected && indicatorStyle]}>
|
||||||
<Text
|
<Text
|
||||||
|
emoji
|
||||||
type={isDesktop || isTablet ? 'xl-bold' : 'lg-bold'}
|
type={isDesktop || isTablet ? 'xl-bold' : 'lg-bold'}
|
||||||
testID={testID ? `${testID}-${item}` : undefined}
|
testID={testID ? `${testID}-${item}` : undefined}
|
||||||
style={[
|
style={[
|
||||||
|
|||||||
@@ -308,6 +308,7 @@ let PostThreadItemLoaded = ({
|
|||||||
style={[styles.meta, styles.metaExpandedLine1, {zIndex: 1}]}>
|
style={[styles.meta, styles.metaExpandedLine1, {zIndex: 1}]}>
|
||||||
<Link style={s.flex1} href={authorHref} title={authorTitle}>
|
<Link style={s.flex1} href={authorHref} title={authorTitle}>
|
||||||
<Text
|
<Text
|
||||||
|
emoji
|
||||||
type="xl-bold"
|
type="xl-bold"
|
||||||
style={[pal.text, a.self_start]}
|
style={[pal.text, a.self_start]}
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
@@ -322,7 +323,11 @@ let PostThreadItemLoaded = ({
|
|||||||
</View>
|
</View>
|
||||||
<View style={styles.meta}>
|
<View style={styles.meta}>
|
||||||
<Link style={s.flex1} href={authorHref} title={authorTitle}>
|
<Link style={s.flex1} href={authorHref} title={authorTitle}>
|
||||||
<Text type="md" style={[pal.textLight]} numberOfLines={1}>
|
<Text
|
||||||
|
emoji
|
||||||
|
type="md"
|
||||||
|
style={[pal.textLight]}
|
||||||
|
numberOfLines={1}>
|
||||||
{sanitizeHandle(post.author.handle, '@')}
|
{sanitizeHandle(post.author.handle, '@')}
|
||||||
</Text>
|
</Text>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ export function ProfileCard({
|
|||||||
moderation.ui('displayName'),
|
moderation.ui('displayName'),
|
||||||
)}
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
<Text type="md" style={[pal.textLight]} numberOfLines={1}>
|
<Text emoji type="md" style={[pal.textLight]} numberOfLines={1}>
|
||||||
{sanitizeHandle(profile.handle, '@')}
|
{sanitizeHandle(profile.handle, '@')}
|
||||||
</Text>
|
</Text>
|
||||||
<ProfileCardPills
|
<ProfileCardPills
|
||||||
|
|||||||
@@ -1,39 +1,35 @@
|
|||||||
import React, {
|
import React, {forwardRef, PropsWithChildren} from 'react'
|
||||||
useState,
|
|
||||||
useCallback,
|
|
||||||
PropsWithChildren,
|
|
||||||
forwardRef,
|
|
||||||
Ref,
|
|
||||||
} from 'react'
|
|
||||||
import {Pressable, PressableProps, StyleProp, ViewStyle} from 'react-native'
|
import {Pressable, PressableProps, StyleProp, ViewStyle} from 'react-native'
|
||||||
import {addStyle} from 'lib/styles'
|
import {View} from 'react-native'
|
||||||
|
|
||||||
|
import {addStyle} from '#/lib/styles'
|
||||||
|
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||||
|
|
||||||
interface PressableWithHover extends PressableProps {
|
interface PressableWithHover extends PressableProps {
|
||||||
hoverStyle: StyleProp<ViewStyle>
|
hoverStyle: StyleProp<ViewStyle>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PressableWithHover = forwardRef(function PressableWithHoverImpl(
|
export const PressableWithHover = forwardRef<
|
||||||
{
|
View,
|
||||||
children,
|
PropsWithChildren<PressableWithHover>
|
||||||
style,
|
>(function PressableWithHoverImpl(
|
||||||
hoverStyle,
|
{children, style, hoverStyle, ...props},
|
||||||
...props
|
ref,
|
||||||
}: PropsWithChildren<PressableWithHover>,
|
|
||||||
ref: Ref<any>,
|
|
||||||
) {
|
) {
|
||||||
const [isHovering, setIsHovering] = useState(false)
|
const {
|
||||||
|
state: hovered,
|
||||||
const onHoverIn = useCallback(() => setIsHovering(true), [setIsHovering])
|
onIn: onHoverIn,
|
||||||
const onHoverOut = useCallback(() => setIsHovering(false), [setIsHovering])
|
onOut: onHoverOut,
|
||||||
style =
|
} = useInteractionState()
|
||||||
typeof style !== 'function' && isHovering
|
|
||||||
? addStyle(style, hoverStyle)
|
|
||||||
: style
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Pressable
|
<Pressable
|
||||||
{...props}
|
{...props}
|
||||||
style={style}
|
style={
|
||||||
|
typeof style !== 'function' && hovered
|
||||||
|
? addStyle(style, hoverStyle)
|
||||||
|
: style
|
||||||
|
}
|
||||||
onHoverIn={onHoverIn}
|
onHoverIn={onHoverIn}
|
||||||
onHoverOut={onHoverOut}
|
onHoverOut={onHoverOut}
|
||||||
ref={ref}>
|
ref={ref}>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {SvgProps} from 'react-native-svg'
|
import {SvgProps} from 'react-native-svg'
|
||||||
|
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme, web} from '#/alf'
|
||||||
import {Button} from '#/components/Button'
|
import {PressableWithHover} from '../../../PressableWithHover'
|
||||||
|
|
||||||
export function ControlButton({
|
export function ControlButton({
|
||||||
active,
|
active,
|
||||||
@@ -21,19 +21,21 @@ export function ControlButton({
|
|||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
return (
|
return (
|
||||||
<Button
|
<PressableWithHover
|
||||||
label={active ? activeLabel : inactiveLabel}
|
accessibilityRole="button"
|
||||||
|
accessibilityHint={active ? activeLabel : inactiveLabel}
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
variant="ghost"
|
style={[
|
||||||
shape="round"
|
a.p_xs,
|
||||||
size="large"
|
a.rounded_full,
|
||||||
style={a.p_2xs}
|
web({transition: 'background-color 0.1s'}),
|
||||||
hoverStyle={{backgroundColor: 'rgba(255, 255, 255, 0.1)'}}>
|
]}
|
||||||
|
hoverStyle={{backgroundColor: 'rgba(255, 255, 255, 0.2)'}}>
|
||||||
{active ? (
|
{active ? (
|
||||||
<ActiveIcon fill={t.palette.white} width={20} />
|
<ActiveIcon fill={t.palette.white} width={20} />
|
||||||
) : (
|
) : (
|
||||||
<InactiveIcon fill={t.palette.white} width={20} />
|
<InactiveIcon fill={t.palette.white} width={20} />
|
||||||
)}
|
)}
|
||||||
</Button>
|
</PressableWithHover>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -358,9 +358,8 @@ export function Controls({
|
|||||||
style={[
|
style={[
|
||||||
a.flex_1,
|
a.flex_1,
|
||||||
a.px_xs,
|
a.px_xs,
|
||||||
a.pt_2xs,
|
a.pb_sm,
|
||||||
a.pb_md,
|
a.gap_sm,
|
||||||
a.gap_md,
|
|
||||||
a.flex_row,
|
a.flex_row,
|
||||||
a.align_center,
|
a.align_center,
|
||||||
]}>
|
]}>
|
||||||
@@ -373,7 +372,11 @@ export function Controls({
|
|||||||
onPress={onPressPlayPause}
|
onPress={onPressPlayPause}
|
||||||
/>
|
/>
|
||||||
<View style={a.flex_1} />
|
<View style={a.flex_1} />
|
||||||
<Text style={{color: t.palette.white, fontVariant: ['tabular-nums']}}>
|
<Text
|
||||||
|
style={[
|
||||||
|
a.px_xs,
|
||||||
|
{color: t.palette.white, fontVariant: ['tabular-nums']},
|
||||||
|
]}>
|
||||||
{formatTime(currentTime)} / {formatTime(duration)}
|
{formatTime(currentTime)} / {formatTime(duration)}
|
||||||
</Text>
|
</Text>
|
||||||
{hasSubtitleTrack && (
|
{hasSubtitleTrack && (
|
||||||
|
|||||||
@@ -56,9 +56,7 @@ export function Text({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (emoji && !childIsString(children)) {
|
if (emoji && !childIsString(children)) {
|
||||||
throw new Error(
|
logger.error('Text: when <Text emoji />, children can only be strings.')
|
||||||
'Text: when <Text emoji />, children can only be strings.',
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -959,6 +959,7 @@ function SearchHistory({
|
|||||||
accessibilityIgnoresInvertColors
|
accessibilityIgnoresInvertColors
|
||||||
/>
|
/>
|
||||||
<Text
|
<Text
|
||||||
|
emoji
|
||||||
style={[pal.text, styles.profileName]}
|
style={[pal.text, styles.profileName]}
|
||||||
numberOfLines={1}>
|
numberOfLines={1}>
|
||||||
{profile.displayName || profile.handle}
|
{profile.displayName || profile.handle}
|
||||||
|
|||||||
@@ -16,19 +16,19 @@ import {useLingui} from '@lingui/react'
|
|||||||
import {StackActions, useNavigation} from '@react-navigation/native'
|
import {StackActions, useNavigation} from '@react-navigation/native'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {usePalette} from '#/lib/hooks/usePalette'
|
||||||
import {makeProfileLink} from '#/lib/routes/links'
|
import {makeProfileLink} from '#/lib/routes/links'
|
||||||
|
import {NavigationProp} from '#/lib/routes/types'
|
||||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
import {s} from '#/lib/styles'
|
import {s} from '#/lib/styles'
|
||||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
|
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
import {precacheProfile} from '#/state/queries/profile'
|
||||||
import {NavigationProp} from 'lib/routes/types'
|
import {SearchInput} from '#/view/com/util/forms/SearchInput'
|
||||||
import {precacheProfile} from 'state/queries/profile'
|
|
||||||
import {Link} from '#/view/com/util/Link'
|
import {Link} from '#/view/com/util/Link'
|
||||||
|
import {Text} from '#/view/com/util/text/Text'
|
||||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import {SearchInput} from 'view/com/util/forms/SearchInput'
|
|
||||||
import {Text} from 'view/com/util/text/Text'
|
|
||||||
import {atoms as a} from '#/alf'
|
import {atoms as a} from '#/alf'
|
||||||
|
|
||||||
let SearchLinkCard = ({
|
let SearchLinkCard = ({
|
||||||
@@ -126,6 +126,7 @@ let SearchProfileCard = ({
|
|||||||
/>
|
/>
|
||||||
<View style={{flex: 1}}>
|
<View style={{flex: 1}}>
|
||||||
<Text
|
<Text
|
||||||
|
emoji
|
||||||
type="lg"
|
type="lg"
|
||||||
style={[s.bold, pal.text, a.self_start]}
|
style={[s.bold, pal.text, a.self_start]}
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
|
|||||||
-382
@@ -36,388 +36,6 @@
|
|||||||
<link rel="preload" as="font" type="font/otf" href="/static/media/Inter-Black.66e9a87f1c921e844ed4.otf">
|
<link rel="preload" as="font" type="font/otf" href="/static/media/Inter-Black.66e9a87f1c921e844ed4.otf">
|
||||||
<link rel="preload" as="font" type="font/otf" href="/static/media/Inter-BlackItalic.27b9f0ad06fd13a7b9da.otf">
|
<link rel="preload" as="font" type="font/otf" href="/static/media/Inter-BlackItalic.27b9f0ad06fd13a7b9da.otf">
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<style>
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-Regular";
|
|
||||||
src: local("Inter-Regular"), url(/static/media/Inter-Regular.1f5ed03b6dd9fd1f9982.otf) format("font/otf");
|
|
||||||
font-weight: 400;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-Italic";
|
|
||||||
src: local("Inter-Italic"), url(/static/media/Inter-Italic.95778eb0c75dc956257e.otf) format("font/otf");
|
|
||||||
font-weight: 400;
|
|
||||||
font-style: italic;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-Medium";
|
|
||||||
src: local("Inter-Medium"), url(/static/media/Inter-Medium.296aa2d65964269836b3.otf) format("font/otf");
|
|
||||||
font-weight: 500;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-MediumItalic";
|
|
||||||
src: local("Inter-MediumItalic"), url(/static/media/Inter-MediumItalic.0e57e17a6311368e2114.otf) format("font/otf");
|
|
||||||
font-weight: 500;
|
|
||||||
font-style: italic;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-SemiBold";
|
|
||||||
src: local("Inter-SemiBold"), url(/static/media/Inter-SemiBold.2277990330981b8409bb.otf) format("font/otf");
|
|
||||||
font-weight: 600;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-SemiBoldItalic";
|
|
||||||
src: local("Inter-SemiBoldItalic"), url(/static/media/Inter-SemiBoldItalic.f62fea3df3a521d6c8a7.otf) format("font/otf");
|
|
||||||
font-weight: 600;
|
|
||||||
font-style: italic;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-Bold";
|
|
||||||
src: local("Inter-Bold"), url(/static/media/Inter-Bold.8d330503e1d034ad68de.otf) format("font/otf");
|
|
||||||
font-weight: 700;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-BoldItalic";
|
|
||||||
src: local("Inter-BoldItalic"), url(/static/media/Inter-BoldItalic.bb17e63f9baa0d861a20.otf) format("font/otf");
|
|
||||||
font-weight: 700;
|
|
||||||
font-style: italic;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-ExtraBold";
|
|
||||||
src: local("Inter-ExtraBold"), url(/static/media/Inter-ExtraBold.ff2581a193bf6b7e0b06.otf) format("font/otf");
|
|
||||||
font-weight: 800;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-ExtraBoldItalic";
|
|
||||||
src: local("Inter-ExtraBoldItalic"), url(/static/media/Inter-ExtraBoldItalic.0e50b40728d24d40fdf4.otf) format("font/otf");
|
|
||||||
font-weight: 800;
|
|
||||||
font-style: italic;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-Black";
|
|
||||||
src: local("Inter-Black"), url(/static/media/Inter-Black.66e9a87f1c921e844ed4.otf) format("font/otf");
|
|
||||||
font-weight: 900;
|
|
||||||
font-style: normal;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: "Inter-BlackItalic";
|
|
||||||
src: local("Inter-BlackItalic"), url(/static/media/Inter-BlackItalic.27b9f0ad06fd13a7b9da.otf) format("font/otf");
|
|
||||||
font-weight: 900;
|
|
||||||
font-style: italic;
|
|
||||||
font-display: swap;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extend the react-native-web reset:
|
|
||||||
* https://github.com/necolas/react-native-web/blob/master/packages/react-native-web/src/exports/StyleSheet/initialRules.js
|
|
||||||
*/
|
|
||||||
html,
|
|
||||||
body,
|
|
||||||
#root {
|
|
||||||
width: 100%;
|
|
||||||
/* To smooth any scrolling behavior */
|
|
||||||
-webkit-overflow-scrolling: touch;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
/* Allows content to fill the viewport and go beyond the bottom */
|
|
||||||
min-height: 100%;
|
|
||||||
}
|
|
||||||
#root {
|
|
||||||
flex-shrink: 0;
|
|
||||||
flex-basis: auto;
|
|
||||||
flex-grow: 1;
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
|
||||||
/* Prevent text size change on orientation change https://gist.github.com/tfausak/2222823#file-ios-8-web-app-html-L138 */
|
|
||||||
-webkit-text-size-adjust: 100%;
|
|
||||||
height: calc(100% + env(safe-area-inset-top));
|
|
||||||
scrollbar-gutter: stable both-edges;
|
|
||||||
}
|
|
||||||
html, body {
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Liberation Sans", Helvetica, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
#preload {
|
|
||||||
width: 100px;
|
|
||||||
position: fixed;
|
|
||||||
left: 50%;
|
|
||||||
top: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Buttons and inputs have a font set by UA, so we'll have to reset that */
|
|
||||||
button, input, textarea {
|
|
||||||
font: inherit;
|
|
||||||
line-height: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Color theming */
|
|
||||||
/* Default will always be white */
|
|
||||||
:root {
|
|
||||||
--text: black;
|
|
||||||
--background: white;
|
|
||||||
--backgroundLight: hsl(211, 20%, 95%);
|
|
||||||
}
|
|
||||||
/* This gives us a black background when system is dark and we have not loaded the theme/color scheme values in JS */
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
:root {
|
|
||||||
--text: white;
|
|
||||||
--background: black;
|
|
||||||
--backgroundLight: hsl(211, 20%, 20%);
|
|
||||||
color-scheme: dark;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Overwrite those preferences with the selected theme */
|
|
||||||
html.theme--light {
|
|
||||||
--text: black;
|
|
||||||
--background: white;
|
|
||||||
--backgroundLight: hsl(211, 20%, 95%);
|
|
||||||
}
|
|
||||||
html.theme--dark {
|
|
||||||
--text: white;
|
|
||||||
--background: black;
|
|
||||||
--backgroundLight: hsl(211, 20%, 20%);
|
|
||||||
color-scheme: dark;
|
|
||||||
}
|
|
||||||
html.theme--dim {
|
|
||||||
--text: white;
|
|
||||||
--background: hsl(211, 20%, 4%);
|
|
||||||
--backgroundLight: hsl(211, 20%, 10%);
|
|
||||||
color-scheme: dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove autofill styles on Webkit */
|
|
||||||
input:autofill,
|
|
||||||
input:-webkit-autofill,
|
|
||||||
input:-webkit-autofill:hover,
|
|
||||||
input:-webkit-autofill:focus,
|
|
||||||
input:-webkit-autofill:active{
|
|
||||||
-webkit-background-clip: text;
|
|
||||||
-webkit-text-fill-color: var(--text);
|
|
||||||
transition: background-color 5000s ease-in-out 0s;
|
|
||||||
box-shadow: inset 0 0 20px 20px var(--background);
|
|
||||||
background: var(--background);
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
/* Force left-align date/time inputs on iOS mobile */
|
|
||||||
input::-webkit-date-and-time-value {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
display: flex;
|
|
||||||
/* Allows you to scroll below the viewport; default value is visible */
|
|
||||||
overflow-y: auto;
|
|
||||||
overscroll-behavior-y: none;
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
background-color: var(--background);
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
-ms-overflow-style: scrollbar;
|
|
||||||
font-synthesis-weight: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove default link styling */
|
|
||||||
a {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
a[role="link"]:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
a[role="link"][data-no-underline="1"]:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Styling hacks */
|
|
||||||
*[data-word-wrap] {
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
*[data-stable-gutters] {
|
|
||||||
scrollbar-gutter: stable both-edges;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ProseMirror */
|
|
||||||
.ProseMirror {
|
|
||||||
min-height: 140px;
|
|
||||||
}
|
|
||||||
.ProseMirror-dark {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.ProseMirror p {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.ProseMirror p.is-editor-empty:first-child::before {
|
|
||||||
color: #8d8e96;
|
|
||||||
content: attr(data-placeholder);
|
|
||||||
float: left;
|
|
||||||
height: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
.ProseMirror .mention {
|
|
||||||
color: #0085ff;
|
|
||||||
}
|
|
||||||
.ProseMirror a,
|
|
||||||
.ProseMirror .autolink {
|
|
||||||
color: #0085ff;
|
|
||||||
}
|
|
||||||
/* OLLIE: TODO -- this is not accessible */
|
|
||||||
/* Remove focus state on inputs */
|
|
||||||
.ProseMirror-focused {
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
textarea:focus,
|
|
||||||
input:focus {
|
|
||||||
outline: 0;
|
|
||||||
}
|
|
||||||
.tippy-content .items {
|
|
||||||
width: fit-content;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tooltips */
|
|
||||||
[data-tooltip] {
|
|
||||||
position: relative;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
[data-tooltip]::after {
|
|
||||||
content: attr(data-tooltip);
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateY(100%) translateY(8px) translateX(-50%);
|
|
||||||
padding: 4px 10px;
|
|
||||||
border-radius: 10px;
|
|
||||||
background: var(--backgroundLight);
|
|
||||||
color: var(--text);
|
|
||||||
text-align: center;
|
|
||||||
white-space: nowrap;
|
|
||||||
font-size: 12px;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
[data-tooltip]::before {
|
|
||||||
content: '';
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
border-bottom: 6px solid var(--backgroundLight);
|
|
||||||
border-left: 6px solid transparent;
|
|
||||||
border-right: 6px solid transparent;
|
|
||||||
bottom: 0;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateY(100%) translateY(2px) translateX(-50%);
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
[data-tooltip]:hover::after,
|
|
||||||
[data-tooltip]:hover::before {
|
|
||||||
display:block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NativeDropdown component */
|
|
||||||
.radix-dropdown-item:focus,
|
|
||||||
.nativeDropdown-item:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Spinner component */
|
|
||||||
@keyframes rotate {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.rotate-500ms {
|
|
||||||
position: absolute;
|
|
||||||
inset:0;
|
|
||||||
animation: rotate 500ms linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes avatarHoverFadeIn {
|
|
||||||
from { opacity: 0; }
|
|
||||||
to { opacity: 1; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes avatarHoverFadeOut {
|
|
||||||
from { opacity: 1; }
|
|
||||||
to { opacity: 0; }
|
|
||||||
}
|
|
||||||
|
|
||||||
.force-no-clicks > *,
|
|
||||||
.force-no-clicks * {
|
|
||||||
pointer-events: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=range][orient=vertical] {
|
|
||||||
writing-mode: vertical-lr;
|
|
||||||
direction: rtl;
|
|
||||||
appearance: slider-vertical;
|
|
||||||
width: 16px;
|
|
||||||
vertical-align: bottom;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
appearance: none;
|
|
||||||
background: transparent;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="range"][orient=vertical]::-webkit-slider-runnable-track {
|
|
||||||
background: white;
|
|
||||||
height: 100%;
|
|
||||||
width: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="range"][orient=vertical]::-moz-range-track {
|
|
||||||
background: white;
|
|
||||||
height: 100%;
|
|
||||||
width: 4px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="range"]::-webkit-slider-thumb {
|
|
||||||
-webkit-appearance: none;
|
|
||||||
appearance: none;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: white;
|
|
||||||
height: 16px;
|
|
||||||
width: 16px;
|
|
||||||
margin-left: -6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="range"][orient=vertical]::-moz-range-thumb {
|
|
||||||
border: none;
|
|
||||||
border-radius: 50%;
|
|
||||||
background-color: white;
|
|
||||||
height: 16px;
|
|
||||||
width: 16px;
|
|
||||||
margin-left: -6px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
Reference in New Issue
Block a user