From 4e8d86db317864257f6416cd867d7bb07baca6d0 Mon Sep 17 00:00:00 2001 From: Mary <148872143+mary-ext@users.noreply.github.com> Date: Mon, 23 Sep 2024 21:38:04 +0700 Subject: [PATCH] Let Expo/Webpack handle CSS assets (#3942) * chore: handle built css assets * chore: let prettier handle css code * refactor: let webpack build css assets * chore: prettier on bskyembed * chore: touch empty.txt on css directory * chore: do the same to the workflow --- .github/workflows/golang-test-lint.yml | 4 +- .prettierignore | 4 +- Dockerfile.embedr | 1 + bskyembed/src/index.css | 2 +- bskyweb/.gitignore | 4 + bskyweb/static/css/.gitkeep | 0 bskyweb/templates/base.html | 381 ----------------------- package.json | 2 +- scripts/post-web-build.js | 25 +- src/App.web.tsx | 1 + src/style.css | 403 +++++++++++++++++++++++++ web/index.html | 382 ----------------------- 12 files changed, 440 insertions(+), 769 deletions(-) create mode 100644 bskyweb/static/css/.gitkeep create mode 100644 src/style.css diff --git a/.github/workflows/golang-test-lint.yml b/.github/workflows/golang-test-lint.yml index 36e28841d5..c8124dbade 100644 --- a/.github/workflows/golang-test-lint.yml +++ b/.github/workflows/golang-test-lint.yml @@ -21,7 +21,7 @@ jobs: with: go-version: '1.22' - 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 run: cd bskyweb/ && make check - name: Build (binary) @@ -38,6 +38,6 @@ jobs: with: go-version: '1.22' - 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 run: cd bskyweb/ && make lint diff --git a/.prettierignore b/.prettierignore index 641a1b8bfc..8ccbae2148 100644 --- a/.prettierignore +++ b/.prettierignore @@ -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 * !**/*.js @@ -7,6 +7,8 @@ !**/*.tsx !*/ +!**/*.css + # More specific ignores go below. .expo android diff --git a/Dockerfile.embedr b/Dockerfile.embedr index 9ff04aa5c7..663cbcfc51 100644 --- a/Dockerfile.embedr +++ b/Dockerfile.embedr @@ -40,6 +40,7 @@ RUN find ./bskyweb/embedr-static && find ./bskyweb/embedr-templates && find ./bs # hack around issue with empty directory and go:embed RUN touch bskyweb/static/js/empty.txt +RUN touch bskyweb/static/css/empty.txt RUN touch bskyweb/static/media/empty.txt # diff --git a/bskyembed/src/index.css b/bskyembed/src/index.css index 23457ec28d..22b2b8be5c 100644 --- a/bskyembed/src/index.css +++ b/bskyembed/src/index.css @@ -4,4 +4,4 @@ .break-word { word-break: break-word; -} \ No newline at end of file +} diff --git a/bskyweb/.gitignore b/bskyweb/.gitignore index 05b3ad7ab5..a63a381f94 100644 --- a/bskyweb/.gitignore +++ b/bskyweb/.gitignore @@ -10,6 +10,10 @@ static/js/*.js static/js/*.map static/js/*.js.LICENSE.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/empty.txt templates/scripts.html diff --git a/bskyweb/static/css/.gitkeep b/bskyweb/static/css/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/bskyweb/templates/base.html b/bskyweb/templates/base.html index 609c17c7ce..eaa31aa4a3 100644 --- a/bskyweb/templates/base.html +++ b/bskyweb/templates/base.html @@ -32,387 +32,6 @@ --> - {% include "scripts.html" %} diff --git a/package.json b/package.json index 05b5f086db..e3aff1fe0c 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "web": "expo start --web", "use-build-number": "./scripts/useBuildNumberEnv.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-ios": "yarn use-build-number-with-bump eas build -p ios", "build-android": "yarn use-build-number-with-bump eas build -p android", diff --git a/scripts/post-web-build.js b/scripts/post-web-build.js index baaa7cb8b7..7bbee38554 100644 --- a/scripts/post-web-build.js +++ b/scripts/post-web-build.js @@ -20,7 +20,30 @@ console.log(`Writing ${templateFile}`) const outputFile = entrypoints .map(name => { const file = path.basename(name) - return `` + const ext = path.extname(file) + + if (ext === '.js') { + return `` + } + if (ext === '.css') { + return `` + } + + return '' }) .join('\n') 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') diff --git a/src/App.web.tsx b/src/App.web.tsx index c81ed10d33..7d98737a3b 100644 --- a/src/App.web.tsx +++ b/src/App.web.tsx @@ -1,5 +1,6 @@ import 'lib/sentry' // must be near top import 'view/icons' +import './style.css' import React, {useEffect, useState} from 'react' import {KeyboardProvider} from 'react-native-keyboard-controller' diff --git a/src/style.css b/src/style.css new file mode 100644 index 0000000000..29e9770e32 --- /dev/null +++ b/src/style.css @@ -0,0 +1,403 @@ +@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 { + 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; +} diff --git a/web/index.html b/web/index.html index 3a132d25b8..512178327f 100644 --- a/web/index.html +++ b/web/index.html @@ -36,388 +36,6 @@ --> - -