Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update from main #337

Merged
merged 29 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
25e1314
s/Calckey/Firefish
cheeaun Nov 25, 2023
1422c5d
Disable Switch post menu if no post instance yet
cheeaun Nov 25, 2023
7019c09
Better resolving of links
cheeaun Nov 25, 2023
4f41646
Multiple fixes on composer highlighting
cheeaun Nov 26, 2023
a579f27
Upgrade vite-plugin-pwa
cheeaun Nov 26, 2023
cbf4ea5
Add 1 option for smaller text size
cheeaun Nov 27, 2023
910b72b
Make settings page work for very small viewports or super large text …
cheeaun Nov 27, 2023
d27de23
Disable highlighting if slow perf
cheeaun Nov 30, 2023
89fb1bb
Experiment show replies count for questions
cheeaun Nov 30, 2023
af503ac
Upgrade dependencies
cheeaun Dec 1, 2023
34e2fe3
Attempt to fix theme-color bug
cheeaun Dec 1, 2023
d1bfbf1
Update integrity information in the package lock
natsukagami Dec 1, 2023
bfcb314
Merge pull request #341 from natsukagami/fix-pkg-lock-integrity
cheeaun Dec 3, 2023
2ad72a6
In case they're undefined
cheeaun Dec 3, 2023
810596b
Fix history key might be undefined in hashtag object
cheeaun Dec 3, 2023
f98306e
No need render div if no content
cheeaun Dec 3, 2023
012e944
Slight style realignment to post carousels
cheeaun Dec 3, 2023
cbb7378
Guard against invalid URLs
cheeaun Dec 3, 2023
f7e755d
Running npm i rearranged these
cheeaun Dec 3, 2023
902149e
Upgrade dependencies
cheeaun Dec 4, 2023
ac05fab
Experiment widen multiple-media figure
cheeaun Dec 4, 2023
2563b23
Prevent scrolling inside status carousel link
cheeaun Dec 4, 2023
99b4842
Apply grid to specific classes instead
cheeaun Dec 5, 2023
222786f
Exclude wide media for status cards
cheeaun Dec 5, 2023
66746eb
Potential fix for weird carousel bug on Firefox
cheeaun Dec 5, 2023
92a109d
Upgrade dependencies
cheeaun Dec 5, 2023
94c2f43
Add basic unicode awareness to mention highlighting
cheeaun Dec 5, 2023
5be3e22
Reduce the widening
cheeaun Dec 5, 2023
8009a8d
What's with all this math
cheeaun Dec 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,093 changes: 1,072 additions & 21 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"react-intersection-observer": "~9.5.3",
"react-quick-pinch-zoom": "~5.1.0",
"react-router-dom": "6.6.2",
"runes2": "~1.1.3",
"string-length": "5.0.1",
"swiped-events": "~1.1.9",
"toastify-js": "~1.12.0",
Expand All @@ -46,15 +47,15 @@
"devDependencies": {
"@preact/preset-vite": "~2.7.0",
"@trivago/prettier-plugin-sort-imports": "~4.3.0",
"postcss": "~8.4.31",
"postcss-dark-theme-class": "~1.0.0",
"postcss": "~8.4.32",
"postcss-dark-theme-class": "~1.1.0",
"postcss-preset-env": "~9.3.0",
"twitter-text": "~3.1.0",
"vite": "~5.0.2",
"vite": "~5.0.5",
"vite-plugin-generate-file": "~0.1.1",
"vite-plugin-html-config": "~1.0.11",
"vite-plugin-pwa": "~0.17.0",
"vite-plugin-remove-console": "~2.1.1",
"vite-plugin-pwa": "~0.17.3",
"vite-plugin-remove-console": "~2.2.0",
"workbox-cacheable-response": "~7.0.0",
"workbox-expiration": "~7.0.0",
"workbox-routing": "~7.0.0",
Expand Down
21 changes: 17 additions & 4 deletions src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -946,8 +946,8 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
position: absolute;
left: 0;
font-size: 10px;
color: var(--carousel-color);
padding: 8px;
color: var(--text-insignificant-color);
padding: 6px;
}

.ui-state {
Expand All @@ -966,9 +966,17 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
animation: appear 0.2s ease-out;
border: 1px solid var(--outline-color);
background-color: var(--bg-blur-color);
border-radius: 8px;
overflow: hidden;
border-radius: 16px;
overflow: clip;
box-shadow: 0 1px var(--bg-color);

&:has(.status-badge:not(:empty)) {
border-top-right-radius: 8px;
}

.status-carousel.boosts-carousel & {
border-top-left-radius: 8px;
}
}
.status-carousel-link::focus {
background-color: var(--link-bg-hover-color);
Expand Down Expand Up @@ -1113,6 +1121,11 @@ a[href^='http'][rel*='nofollow']:visited:not(:has(div)) {
flex-grow: 1;
background-color: var(--backdrop-solid-color);
animation: appear 0.3s var(--timing-function) both;
transition: width 0.3s var(--timing-function);

&:only-child {
width: 100%;
}
}
.media-modal-container.loading {
display: flex;
Expand Down
26 changes: 26 additions & 0 deletions src/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,32 @@ setTimeout(() => {
// );
})();

// Possible fix for iOS PWA theme-color bug
// It changes when loading web pages in "webview"
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
if (isIOS) {
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
// Get current color scheme
const colorScheme = window.matchMedia('(prefers-color-scheme: dark)')
.matches
? 'dark'
: 'light';
// Get current theme-color
const $meta = document.querySelector(
`meta[name="theme-color"][media*="${colorScheme}"]`,
);
const color = $meta?.getAttribute('content');
if (color) {
$meta.content = '';
setTimeout(() => {
$meta.content = color;
}, 10);
}
}
});
}

subscribe(states, (changes) => {
for (const [action, path, value, prevValue] of changes) {
// Change #app dataset based on settings.shortcutsViewMode
Expand Down
8 changes: 7 additions & 1 deletion src/components/compose.css
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,8 @@
grid-template-columns: 1fr 1fr;
}

> * {
> .compose-field,
> .compose-highlight {
grid-area: 1 / 1 / 2 / 2;
}

Expand All @@ -653,6 +654,11 @@
white-space: pre-wrap;
min-height: 5em;
max-height: 50vh;
scrollbar-width: none;

&::-webkit-scrollbar {
display: none;
}

/* Follow textarea styles */
@media (min-width: 40em) {
Expand Down
47 changes: 37 additions & 10 deletions src/components/compose.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import equal from 'fast-deep-equal';
import { forwardRef } from 'preact/compat';
import { useEffect, useMemo, useRef, useState } from 'preact/hooks';
import { useHotkeys } from 'react-hotkeys-hook';
import { substring } from 'runes2';
import stringLength from 'string-length';
import { uid } from 'uid/single';
import { useDebouncedCallback, useThrottledCallback } from 'use-debounce';
Expand Down Expand Up @@ -107,8 +108,8 @@ function countableText(inputText) {
// https://github.com/mastodon/mastodon/blob/c03bd2a238741a012aa4b98dc4902d6cf948ab63/app/models/account.rb#L69
const USERNAME_RE = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i;
const MENTION_RE = new RegExp(
`(^|[^=\\/\\w])(@${USERNAME_RE.source}(?:@[\\w.-]+[\\w]+)?)`,
'ig',
`(^|[^=\\/\\w])(@${USERNAME_RE.source}(?:@[\\p{L}\\w.-]+[\\w]+)?)`,
'uig',
);

// AI-generated, all other regexes are too complicated
Expand All @@ -131,25 +132,27 @@ function highlightText(text, { maxCharacters = Infinity }) {
const { composerCharacterCount } = states;
let leftoverHTML = '';
if (composerCharacterCount > maxCharacters) {
const leftoverCount = composerCharacterCount - maxCharacters;
// NOTE: runes2 substring considers surrogate pairs
// const leftoverCount = composerCharacterCount - maxCharacters;
// Highlight exceeded characters
leftoverHTML =
'<mark class="compose-highlight-exceeded">' +
html.slice(-leftoverCount) +
// html.slice(-leftoverCount) +
substring(html, maxCharacters) +
'</mark>';
html = html.slice(0, -leftoverCount);
// html = html.slice(0, -leftoverCount);
html = substring(html, 0, maxCharacters);
return html + leftoverHTML;
}

html = html
return html
.replace(urlRegexObj, '$2<mark class="compose-highlight-url">$3</mark>') // URLs
.replace(MENTION_RE, '$1<mark class="compose-highlight-mention">$2</mark>') // Mentions
.replace(HASHTAG_RE, '$1<mark class="compose-highlight-hashtag">$2</mark>') // Hashtags
.replace(
SCAN_RE,
'$1<mark class="compose-highlight-emoji-shortcode">$2</mark>',
); // Emoji shortcodes

return html + leftoverHTML;
}

function Compose({
Expand Down Expand Up @@ -1482,12 +1485,30 @@ const Textarea = forwardRef((props, ref) => {
resizeObserver.observe(textarea);
}, []);

const slowHighlightPerf = useRef(0); // increment if slow
const composeHighlightRef = useRef();
const throttleHighlightText = useThrottledCallback((text) => {
if (!composeHighlightRef.current) return;
if (slowHighlightPerf.current > 3) {
// After 3 times of lag, disable highlighting
composeHighlightRef.current.innerHTML = '';
composeHighlightRef.current = null; // Destroy the whole thing
throttleHighlightText?.cancel?.();
return;
}
let start;
let end;
if (slowHighlightPerf.current <= 3) start = Date.now();
composeHighlightRef.current.innerHTML =
highlightText(text, {
maxCharacters,
}) + '\n';
if (slowHighlightPerf.current <= 3) end = Date.now();
console.debug('HIGHLIGHT PERF', { start, end, diff: end - start });
if (start && end && end - start > 50) {
// if slow, increment
slowHighlightPerf.current++;
}
// Newline to prevent multiple line breaks at the end from being collapsed, no idea why
}, 500);

Expand Down Expand Up @@ -1538,13 +1559,17 @@ const Textarea = forwardRef((props, ref) => {
target.setRangeText('', pos, selectionStart);
}
autoResizeTextarea(target);
target.dispatchEvent(new Event('input'));
}
}
} catch (e) {
// silent fail
console.error(e);
}
}
if (composeHighlightRef.current) {
composeHighlightRef.current.scrollTop = target.scrollTop;
}
}}
onInput={(e) => {
const { target } = e;
Expand All @@ -1560,8 +1585,10 @@ const Textarea = forwardRef((props, ref) => {
// '--text-weight': (1 + charCount / 140).toFixed(1) || 1,
}}
onScroll={(e) => {
const { scrollTop } = e.target;
composeHighlightRef.current.scrollTop = scrollTop;
if (composeHighlightRef.current) {
const { scrollTop } = e.target;
composeHighlightRef.current.scrollTop = scrollTop;
}
}}
/>
<div
Expand Down
16 changes: 9 additions & 7 deletions src/components/link.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ const Link = forwardRef((props, ref) => {

// Handle encodeURIComponent of searchParams values
if (!!hash && hash !== '/' && hash.includes('?')) {
const parsedHash = new URL(hash, location.origin); // Fake base URL
if (parsedHash.searchParams.size) {
const searchParamsStr = Array.from(parsedHash.searchParams.entries())
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join('&');
hash = parsedHash.pathname + '?' + searchParamsStr;
}
try {
const parsedHash = new URL(hash, location.origin); // Fake base URL
if (parsedHash.searchParams.size) {
const searchParamsStr = Array.from(parsedHash.searchParams.entries())
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join('&');
hash = parsedHash.pathname + '?' + searchParamsStr;
}
} catch (e) {}
}

const isActive = hash === to || decodeURIComponent(hash) === to;
Expand Down
38 changes: 38 additions & 0 deletions src/components/status.css
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,14 @@
color: inherit;
} */

.status .content-comment-hint {
margin-top: 0.25em;
font-size: 90%;
display: flex;
gap: 4px;
align-items: center;
}

.status.compact-thread .spoiler-badge {
font-size: smaller;
color: var(--button-bg-color);
Expand Down Expand Up @@ -676,6 +684,24 @@
/* min-height: 0 !important; */
max-height: none !important;
}
.status-carousel .status .media-container:not(.status-card .media-container) {
margin-inline: -16px;
max-width: calc(100% + 16px + 16px) !important;

figure figcaption {
padding-inline: 16px !important;
}

&:not(.media-figure-multiple .media-container) {
margin-bottom: -16px;
}

.media {
--media-radius: 0;
--media-radius-inner: 0;
box-sizing: border-box;
}
}
.status:not(.large):not(.status-carousel .status)
.media-container.media-eq1:has([data-orientation='portrait']) {
width: 85%;
Expand All @@ -686,6 +712,17 @@
/* height: 200px; */
max-height: max(200px, 40vh);
}
.status.medium .content ~ * .media-container:is(.media-eq2, .media-gt2),
.status.medium .content ~ .media-container:is(.media-eq2, .media-gt2) {
/* 50px = avatar size */
margin-left: calc(-1 * ((50px / 2)));
/*
outer padding = 16px
gap = 12px
so... 16 - 12 = 4
*/
margin-right: -4px;
}
.status.large :is(.media-container, .media-container.media-gt2) {
height: auto;
/* min-height: 160px; */
Expand All @@ -700,6 +737,7 @@
overflow: hidden;
min-height: 80px;
border: var(--media-border-width) solid var(--outline-color);
vertical-align: top;
}
.status .media-container:not(.media-eq1) .media {
aspect-ratio: auto !important;
Expand Down
Loading