Merge pull request #9 from cheeaun/main

Update from main
This commit is contained in:
Chee Aun 2022-12-17 18:37:19 +08:00 committed by GitHub
commit 3b8592e946
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 127 additions and 109 deletions

View file

@ -93,11 +93,15 @@ function Compose({
replyToStatus.account.acct,
...replyToStatus.mentions.map((m) => m.acct),
]);
textareaRef.current.value = `${[...mentions]
.filter((m) => m !== currentAccountInfo.acct) // Excluding self
.map((m) => `@${m}`)
.join(' ')} `;
textareaRef.current.dispatchEvent(new Event('input'));
const allMentions = [...mentions].filter(
(m) => m !== currentAccountInfo.acct,
);
if (allMentions.length > 0) {
textareaRef.current.value = `${allMentions
.map((m) => `@${m}`)
.join(' ')} `;
textareaRef.current.dispatchEvent(new Event('input'));
}
textareaRef.current.focus();
}
setVisibility(visibility);

View file

@ -294,6 +294,7 @@
}
.status .media-audio {
border: 0;
min-height: 0;
}
.status .media-audio audio {
width: 100%;
@ -471,7 +472,7 @@ a.card:hover {
.status .actions > button.plain.reblog-button:hover {
color: var(--reblog-color);
}
.status .actions > button.plain.reblog-button.reblogged {
.status .actions > button.plain.reblog-button.checked {
color: var(--reblog-color);
border-color: var(--reblog-color);
}
@ -490,13 +491,13 @@ a.card:hover {
opacity: 0;
}
}
.status .actions > button.plain.reblog-button.reblogged .icon {
.status .actions > button.plain.reblog-button.checked .icon {
animation: reblogged 1s ease-in-out;
}
.status .actions > button.plain.favourite-button:hover {
color: var(--favourite-color);
}
.status .actions > button.plain.favourite-button.favourited {
.status .actions > button.plain.favourite-button.checked {
color: var(--favourite-color);
border-color: var(--favourite-color);
}
@ -518,11 +519,11 @@ a.card:hover {
opacity: 0;
}
}
.status .actions > button.plain.favourite-button.favourited .icon {
.status .actions > button.plain.favourite-button.checked .icon {
transform-origin: bottom center;
animation: hearted 1s ease-in-out;
}
.status .actions > button.plain.bookmark-button.bookmarked {
.status .actions > button.plain.bookmark-button.checked {
color: var(--link-color);
border-color: var(--link-color);
}
@ -544,7 +545,7 @@ a.card:hover {
opacity: 1;
}
}
.status .actions > button.plain.bookmark-button.bookmarked .icon {
.status .actions > button.plain.bookmark-button.checked .icon {
animation: bookmarked 1s ease-in-out;
}

View file

@ -220,8 +220,10 @@ function Card({ card }) {
height={height}
loading="lazy"
alt=""
onError={() => {
this.style.display = 'none';
onError={(e) => {
try {
e.target.style.display = 'none';
} catch (e) {}
}}
/>
<div class="meta-container">
@ -855,42 +857,35 @@ function Status({
)}
</div>
<div class="actions">
<button
type="button"
title="Comment"
class="plain reply-button"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
<StatusButton
title="Reply"
alt="Comments"
class="reply-button"
icon="comment"
count={repliesCount}
onClick={() => {
states.showCompose = {
replyToStatus: status,
};
}}
>
<Icon icon="comment" size="l" alt="Reply" />
{!!repliesCount && (
<>
{' '}
<small>{shortenNumber(repliesCount)}</small>
</>
)}
</button>
/>
{/* TODO: if visibility = private, only can reblog own statuses */}
{visibility !== 'direct' && (
<button
type="button"
title={reblogged ? 'Unboost' : 'Boost'}
class={`plain reblog-button ${reblogged ? 'reblogged' : ''}`}
disabled={actionsUIState === 'boost-loading'}
onClick={async (e) => {
e.preventDefault();
e.stopPropagation();
const yes = confirm(
reblogged ? 'Unboost this status?' : 'Boost this status?',
);
if (!yes) return;
setActionsUIState('boost-loading');
<StatusButton
checked={reblogged}
title={['Boost', 'Unboost']}
alt={['Boost', 'Boosted']}
class="reblog-button"
icon="rocket"
count={reblogsCount}
onClick={async () => {
try {
// Optimistic
states.statuses.set(id, {
...status,
reblogged: !reblogged,
reblogsCount: reblogsCount + (reblogged ? -1 : 1),
});
if (reblogged) {
const newStatus = await masto.statuses.unreblog(id);
states.statuses.set(newStatus.id, newStatus);
@ -903,38 +898,26 @@ function Status({
);
}
} catch (e) {
alert(e);
console.error(e);
} finally {
setActionsUIState(null);
}
}}
>
<Icon
icon="rocket"
size="l"
alt={reblogged ? 'Boosted' : 'Boost'}
/>
{!!reblogsCount && (
<>
{' '}
<small>{shortenNumber(reblogsCount)}</small>
</>
)}
</button>
/>
)}
<button
type="button"
title={favourited ? 'Unfavourite' : 'Favourite'}
class={`plain favourite-button ${
favourited ? 'favourited' : ''
}`}
disabled={actionsUIState === 'favourite-loading'}
onClick={async (e) => {
e.preventDefault();
e.stopPropagation();
setActionsUIState('favourite-loading');
<StatusButton
checked={favourited}
title={['Favourite', 'Unfavourite']}
alt={['Favourite', 'Favourited']}
class="favourite-button"
icon="heart"
count={favouritesCount}
onClick={async () => {
try {
// Optimistic
states.statuses.set(statusID, {
...status,
favourited: !favourited,
favouritesCount: favouritesCount + (favourited ? -1 : 1),
});
if (favourited) {
const newStatus = await masto.statuses.unfavourite(id);
states.statuses.set(newStatus.id, newStatus);
@ -943,37 +926,23 @@ function Status({
states.statuses.set(newStatus.id, newStatus);
}
} catch (e) {
alert(e);
console.error(e);
} finally {
setActionsUIState(null);
}
}}
>
<Icon
icon="heart"
size="l"
alt={favourited ? 'Favourited' : 'Favourite'}
/>
{!!favouritesCount && (
<>
{' '}
<small>{shortenNumber(favouritesCount)}</small>
</>
)}
</button>
<button
type="button"
title={bookmarked ? 'Unbookmark' : 'Bookmark'}
class={`plain bookmark-button ${
bookmarked ? 'bookmarked' : ''
}`}
disabled={actionsUIState === 'bookmark-loading'}
onClick={async (e) => {
e.preventDefault();
e.stopPropagation();
setActionsUIState('bookmark-loading');
/>
<StatusButton
checked={bookmarked}
title={['Bookmark', 'Unbookmark']}
alt={['Bookmark', 'Bookmarked']}
class="bookmark-button"
icon="bookmark"
onClick={async () => {
try {
// Optimistic
states.statuses.set(statusID, {
...status,
bookmarked: !bookmarked,
});
if (bookmarked) {
const newStatus = await masto.statuses.unbookmark(id);
states.statuses.set(newStatus.id, newStatus);
@ -982,19 +951,10 @@ function Status({
states.statuses.set(newStatus.id, newStatus);
}
} catch (e) {
alert(e);
console.error(e);
} finally {
setActionsUIState(null);
}
}}
>
<Icon
icon="bookmark"
size="l"
alt={bookmarked ? 'Bookmarked' : 'Bookmark'}
/>
</button>
/>
{isSelf && (
<span class="menu-container">
<button type="button" title="More" class="plain more-button">
@ -1154,4 +1114,57 @@ function Status({
);
}
function StatusButton({
checked,
count,
class: className,
title,
alt,
icon,
onClick,
...props
}) {
if (typeof title === 'string') {
title = [title, title];
}
if (typeof alt === 'string') {
alt = [alt, alt];
}
const [buttonTitle, setButtonTitle] = useState(title[0] || '');
const [iconAlt, setIconAlt] = useState(alt[0] || '');
useEffect(() => {
if (checked) {
setButtonTitle(title[1] || '');
setIconAlt(alt[1] || '');
} else {
setButtonTitle(title[0] || '');
setIconAlt(alt[0] || '');
}
}, [checked, title, alt]);
return (
<button
type="button"
title={buttonTitle}
class={`plain ${className} ${checked ? 'checked' : ''}`}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
onClick(e);
}}
{...props}
>
<Icon icon={icon} size="l" alt={iconAlt} />
{!!count && (
<>
{' '}
<small>{shortenNumber(count)}</small>
</>
)}
</button>
);
}
export default Status;

View file

@ -188,7 +188,7 @@ select.plain {
pre code,
code {
font-size: 95%;
font-size: 90%;
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier,
monospace;
}

View file

@ -20,7 +20,7 @@ function enhanceContent(content, opts = {}) {
// Convert :shortcode: to <img />
let textNodes = extractTextNodes(dom);
textNodes.forEach((node) => {
let html = node.nodeValue;
let html = node.nodeValue.replace(/</g, '&lt;').replace(/>/g, '&gt;');
if (emojis) {
html = emojifyText(html, emojis);
}
@ -34,7 +34,7 @@ function enhanceContent(content, opts = {}) {
// Convert `code` to <code>code</code>
textNodes = extractTextNodes(dom);
textNodes.forEach((node) => {
let html = node.nodeValue;
let html = node.nodeValue.replace(/</g, '&lt;').replace(/>/g, '&gt;');
if (/`[^`]+`/g.test(html)) {
html = html.replaceAll(/(`[^]+?`)/g, '<code>$1</code>');
}