Merge branch 'cheeaun:main' into width-columns-css-fix

This commit is contained in:
Nathan Sparrow 2024-10-17 00:39:36 -04:00 committed by GitHub
commit ef60f96816
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
60 changed files with 17553 additions and 16971 deletions

View file

@ -1,41 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
- Which site: [e.g. dev.phanpy.social OR phanpy.social]
- Which site version: [On Phanpy, go to Settings -> About]
- Which instance: [e.g. mastodon.social]
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

81
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View file

@ -0,0 +1,81 @@
name: "Bug report"
description: "Create a report to help us improve"
labels:
- "bug"
body:
- type: input
id: "site"
attributes:
label: "Site"
description: |-
What site(s) did you encounter this bug on?
placeholder: |-
phanpy.social
- type: input
id: "version"
attributes:
label: "Version"
description: |-
Which Phanpy version(s) did you encounter this bug on?
You can see and copy your current version by opening the Settings menu and scrolling down to the About section.
placeholder: |-
2024.10.08.0a176e2
- type: input
id: "instance"
attributes:
label: "Instance"
description: |-
Which instance(s) did you encounter this bug on?
placeholder: |-
mastodon.social
- type: textarea
id: "Browser"
attributes:
label: "Browser"
description: |-
Which browser(s) did you encounter this bug on?
placeholder: |-
- Firefox 132.0b5 on Windows 11
- Safari 18 on iOS 18 on iPhone 16 Pro Max
- type: textarea
id: "description"
attributes:
label: "Bug description"
description: |-
A concise description of what the bug is.
If applicable, add screenshots to help explain your problem.
You can paste screenshots here and GitHub will convert them to Markdown for you.
- type: textarea
id: "steps"
attributes:
label: "To reproduce"
description: |-
A list of steps that can be performed to make the bug happen again.
If possible, add screenshots to help demonstrate the steps.
You can paste screenshots here and GitHub will convert them to Markdown for you.
placeholder: |-
1. Go to '...'
2. Click on '...'
3. Scroll down to '...'
4. See error
- type: textarea
id: "behavior"
attributes:
label: "Expected behavior"
description: |-
A concise description of what you expected to happen.
- type: textarea
id: "other"
attributes:
label: "Other"
description: |-
Anything you want to add?

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View file

@ -0,0 +1 @@
blank_issues_enabled: true

View file

@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: 'enhancement'
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View file

@ -0,0 +1,37 @@
name: "Feature request"
description: "Suggest an idea for this project"
labels:
- "enhancement"
body:
- type: textarea
id: "problem"
attributes:
label: "Problem I have"
description: |-
If your request is related to a problem, please provide a clear and concise description of what the problem is.
placeholder: |-
I'm always frustrated when [...]
- type: textarea
id: "solution"
attributes:
label: "Solution I'd like"
description: |-
A clear and concise description of what you want to happen.
- type: textarea
id: "alternatives"
attributes:
label: "Alternatives considered"
description: |-
A clear and concise description of any alternative solutions or features you've considered.
- type: textarea
id: "other"
attributes:
label: "Other"
description: |-
Anything you want to add?

View file

@ -7,6 +7,7 @@ on:
jobs:
auto-pull-request:
if: github.repository == 'cheeaun/phanpy'
runs-on: ubuntu-latest
steps:
- uses: vsoch/pull-request-action@master

View file

@ -319,7 +319,7 @@ Costs involved in running and developing this web app:
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/15791971/medium/88bdda3090339f16f6083390d32bb434_default.png" alt="" width="16" height="16" /> katullo11 (Italian)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/14677260/medium/e53420d200961f48602324e18c091bdc.png" alt="" width="16" height="16" /> Kytta (German)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/16529521/medium/ae6add93a901b0fefa2d9b1077920d73.png" alt="" width="16" height="16" /> llun (Thai)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/16291756/medium/e1c4210f15537394cc764b8bc2dffe37.jpg" alt="" width="16" height="16" /> lucasofchirst (Occitan, Portuguese, Portuguese, Brazilian)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/16291756/medium/2366972cc86287353708aff1ded3f3c1.jpg" alt="" width="16" height="16" /> lucasofchirst (Occitan, Portuguese, Portuguese, Brazilian)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/16537713/medium/825f0bf1a14fc545a76891a52839d86e_default.png" alt="" width="16" height="16" /> marcin.kozinski (Polish)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/13521465/medium/76cb9aa6b753ce900a70478bff7fcea0.png" alt="" width="16" height="16" /> mkljczkk (Polish)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/12882812/medium/77744d8db46e9a3e09030e1a02b7a572.jpeg" alt="" width="16" height="16" /> mojosoeun (Korean)
@ -337,12 +337,14 @@ Costs involved in running and developing this web app:
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/16539171/medium/0ce95ef6b3b0566136191fbedc1563d0.png" alt="" width="16" height="16" /> SadmL_AI (Russian)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/12381015/medium/35e3557fd61d85f9a5b84545d9e3feb4.png" alt="" width="16" height="16" /> shuuji3 (Japanese)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/14565190/medium/79100599131b7776e9803e4b696915a3_default.png" alt="" width="16" height="16" /> Sky_NiniKo (French)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/13143526/medium/30871da23d51d7e41bb02f3c92d7f104.png" alt="" width="16" height="16" /> Steffo99 (Italian)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/16532441/medium/1a47e8d80c95636e02d2260f6e233ca5.png" alt="" width="16" height="16" /> Su5hicz (Czech)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/16530049/medium/683f3581620c6b4a5c753b416ed695a7.jpeg" alt="" width="16" height="16" /> tferrermo (Spanish)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/15752199/medium/7e9efd828c4691368d063b19d19eb894.png" alt="" width="16" height="16" /> tkbremnes (Norwegian Bokmal)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/16527851/medium/649e5a9a8a8cc61ced670d89e9cca082.png" alt="" width="16" height="16" /> tux93 (German)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/14427566/medium/ab733b5044c21867fc5a9d1b22cd2c03.png" alt="" width="16" height="16" /> Vac31. (Lithuanian)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/16026914/medium/e3ca187f354a298ef0c9d02a0ed17be7.jpg" alt="" width="16" height="16" /> valtlai (Finnish)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/16608515/medium/85506c21dce8df07843ca11908ee3951.jpeg" alt="" width="16" height="16" /> vasiriri (Polish)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/16563757/medium/af4556c13862d1fd593b51084a159b75_default.png" alt="" width="16" height="16" /> voyagercy (Chinese Traditional)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/15982109/medium/9c03062bdc1d3c6d384dbfead97c26ba.jpeg" alt="" width="16" height="16" /> xabi_itzultzaile (Basque)
- <img src="https://crowdin-static.downloads.crowdin.com/avatar/16556017/medium/216e0f7a0c35b079920366939a3aaca7_default.png" alt="" width="16" height="16" /> xen4n (Ukrainian)

BIN
design/logo-bw-4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

12
design/logo-bw-4.svg Normal file
View file

@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" clip-rule="evenodd" viewBox="0 0 64 64">
<path fill="none" d="M0 0h63.99v63.99H0z"/>
<clipPath id="a">
<path d="M0 0h63.99v63.99H0z"/>
</clipPath>
<g clip-path="url(#a)">
<path d="M0 0h64.25v63.99H0z"/>
<path fill="#fff" d="M37.77 11.47c14.64 3.75 19.04 16.56 15.9 31.3a12.55 12.55 0 0 1-6.36 8.7c-3.2 1.71-8.07 2.53-15.34.55l-9.64-2.4c-10.68-2.63-13.95-10.89-12.3-17.8 3.62-15.2 15.54-23.48 27.74-20.35Z"/>
<path d="M36.76 15.43c12.29 3.15 15.55 14.11 12.9 26.5-.94 4.43-4.93 9.36-16.66 6.13l-9.68-2.41c-7.85-1.93-10.53-7.8-9.32-12.88 3.02-12.64 12.61-19.94 22.76-17.34Z"/>
<path fill="#fff" d="M27.47 25c-1.46-.7-7.23 3.2-7.66 8.92-.18 2.39 4.55 3.23 5.07-.17.72-4.74 3.71-8.22 2.6-8.76Zm10.75 2c-2.09.32-.39 5.9-.6 10.72-.12 2.8 4.39 3.47 4.7 2.01 1.1-5.07-2.06-13.05-4.1-12.73Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 954 B

BIN
design/logo-wb-4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

12
design/logo-wb-4.svg Normal file
View file

@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" clip-rule="evenodd" viewBox="0 0 64 64">
<path fill="none" d="M0 0h63.99v63.99H0z"/>
<clipPath id="a">
<path d="M0 0h63.99v63.99H0z"/>
</clipPath>
<g clip-path="url(#a)">
<path fill="#fff" d="M0 0h64.25v63.99H0z"/>
<path d="M37.77 11.47c14.64 3.75 19.04 16.56 15.9 31.3a12.55 12.55 0 0 1-6.36 8.7c-3.2 1.71-8.07 2.53-15.34.55l-9.64-2.4c-10.68-2.63-13.95-10.89-12.3-17.8 3.62-15.2 15.54-23.48 27.74-20.35Z"/>
<path fill="#fff" d="M36.76 15.43c12.29 3.15 15.55 14.11 12.9 26.5-.94 4.43-4.93 9.36-16.66 6.13l-9.68-2.41c-7.85-1.93-10.53-7.8-9.32-12.88 3.02-12.64 12.61-19.94 22.76-17.34Z"/>
<path d="M27.47 25c-1.46-.7-7.23 3.2-7.66 8.92-.18 2.39 4.55 3.23 5.07-.17.72-4.74 3.71-8.22 2.6-8.76Zm10.75 2c-2.09.32-.39 5.9-.6 10.72-.12 2.8 4.39 3.47 4.7 2.01 1.1-5.07-2.06-13.05-4.1-12.73Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 954 B

Binary file not shown.

540
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -16,15 +16,15 @@
"readme:i18n-volunteers": "node scripts/update-i18n-volunteers-readme.js"
},
"dependencies": {
"@formatjs/intl-localematcher": "~0.5.4",
"@formatjs/intl-segmenter": "~11.5.7",
"@formatjs/intl-localematcher": "~0.5.5",
"@formatjs/intl-segmenter": "~11.5.9",
"@formkit/auto-animate": "~0.8.2",
"@github/text-expander-element": "~2.7.1",
"@github/text-expander-element": "~2.8.0",
"@iconify-icons/mingcute": "~1.2.9",
"@justinribeiro/lite-youtube": "~1.5.0",
"@lingui/detect-locale": "~4.11.4",
"@lingui/macro": "~4.11.4",
"@lingui/react": "~4.11.4",
"@lingui/detect-locale": "~4.13.0",
"@lingui/macro": "~4.13.0",
"@lingui/react": "~4.13.0",
"@szhsin/react-menu": "~4.2.2",
"compare-versions": "~6.1.1",
"fast-blurhash": "~1.1.4",
@ -36,11 +36,11 @@
"js-cookie": "~3.0.5",
"just-debounce-it": "~3.2.0",
"lz-string": "~1.5.0",
"masto": "~6.8.0",
"masto": "~6.9.0",
"moize": "~6.1.6",
"p-retry": "~6.2.0",
"p-throttle": "~6.2.0",
"preact": "~10.24.0",
"preact": "~10.24.3",
"punycode": "~2.3.1",
"react-hotkeys-hook": "~4.5.1",
"react-intersection-observer": "~9.13.1",
@ -51,22 +51,22 @@
"tinyld": "~1.3.4",
"toastify-js": "~1.12.0",
"uid": "~2.0.2",
"use-debounce": "~10.0.3",
"use-debounce": "~10.0.4",
"use-long-press": "~3.2.0",
"use-resize-observer": "~9.1.0",
"valtio": "2.0.0"
},
"devDependencies": {
"@ianvs/prettier-plugin-sort-imports": "~4.3.1",
"@lingui/cli": "~4.11.4",
"@lingui/vite-plugin": "~4.11.4",
"@lingui/cli": "~4.13.0",
"@lingui/vite-plugin": "~4.13.0",
"@preact/preset-vite": "~2.9.1",
"babel-plugin-macros": "~3.1.0",
"postcss": "~8.4.47",
"postcss-dark-theme-class": "~1.3.0",
"postcss-preset-env": "~10.0.3",
"postcss-preset-env": "~10.0.7",
"twitter-text": "~3.1.0",
"vite": "~5.4.7",
"vite": "~5.4.9",
"vite-plugin-generate-file": "~0.2.0",
"vite-plugin-html-config": "~2.0.2",
"vite-plugin-pwa": "~0.20.5",

View file

@ -413,7 +413,7 @@ function AccountInfo({
<span></span> <Trans>Followers</Trans>
</div>
<div>
<span></span> <Trans>Following</Trans>
<span></span> <Trans id="following.stats">Following</Trans>
</div>
<div>
<span></span> <Trans>Posts</Trans>
@ -739,7 +739,10 @@ function AccountInfo({
// states.showAccount = false;
setTimeout(() => {
states.showGenericAccounts = {
heading: t`Following`,
heading: t({
id: 'following.stats',
message: 'Following',
}),
fetchAccounts: fetchFollowing,
instance,
excludeRelationshipAttrs: isSelf ? ['following'] : [],
@ -753,7 +756,7 @@ function AccountInfo({
<span title={followingCount}>
{shortenNumber(followingCount)}
</span>{' '}
<Trans>Following</Trans>
<Trans id="following.stats">Following</Trans>
<br />
</LinkOrDiv>
<LinkOrDiv

View file

@ -50,6 +50,7 @@ function Avatar({ url, size, alt = '', squircle, ...props }) {
alt={alt}
loading="lazy"
decoding="async"
fetchPriority="low"
crossOrigin={
alphaCache[url] === undefined && !isMissing
? 'anonymous'

View file

@ -197,6 +197,7 @@ function highlightText(text, { maxCharacters = Infinity }) {
// const rtf = new Intl.RelativeTimeFormat();
const RTF = mem((locale) => new Intl.RelativeTimeFormat(locale || undefined));
const LF = mem((locale) => new Intl.ListFormat(locale || undefined));
const CUSTOM_EMOJIS_COUNT = 100;
@ -210,6 +211,7 @@ function Compose({
}) {
const { i18n } = useLingui();
const rtf = RTF(i18n.locale);
const lf = LF(i18n.locale);
console.warn('RENDER COMPOSER');
const { masto, instance } = api();
@ -226,11 +228,11 @@ function Compose({
const {
statuses: {
maxCharacters,
maxMediaAttachments,
maxMediaAttachments, // Beware: it can be undefined!
charactersReservedPerUrl,
} = {},
mediaAttachments: {
supportedMimeTypes = [],
supportedMimeTypes,
imageSizeLimit,
imageMatrixLimit,
videoSizeLimit,
@ -600,15 +602,31 @@ function Compose({
const handleItems = (e) => {
const { items } = e.clipboardData || e.dataTransfer;
const files = [];
const unsupportedFiles = [];
for (let i = 0; i < items.length; i++) {
const item = items[i];
if (item.kind === 'file') {
const file = item.getAsFile();
if (file && supportedMimeTypes.includes(file.type)) {
if (
supportedMimeTypes !== undefined &&
!supportedMimeTypes.includes(file.type)
) {
unsupportedFiles.push(file);
} else {
files.push(file);
}
}
}
if (unsupportedFiles.length > 0) {
alert(
plural(unsupportedFiles.length, {
one: `File ${unsupportedFiles[0].name} is not supported.`,
other: `Files ${lf.format(
unsupportedFiles.map((f) => f.name),
)} are not supported.`,
}),
);
}
if (files.length > 0 && mediaAttachments.length >= maxMediaAttachments) {
alert(
plural(maxMediaAttachments, {
@ -623,16 +641,19 @@ function Compose({
e.preventDefault();
e.stopPropagation();
// Auto-cut-off files to avoid exceeding maxMediaAttachments
const max = maxMediaAttachments - mediaAttachments.length;
const allowedFiles = files.slice(0, max);
if (allowedFiles.length <= 0) {
alert(
plural(maxMediaAttachments, {
one: 'You can only attach up to 1 file.',
other: 'You can only attach up to # files.',
}),
);
return;
let allowedFiles = files;
if (maxMediaAttachments !== undefined) {
const max = maxMediaAttachments - mediaAttachments.length;
allowedFiles = allowedFiles.slice(0, max);
if (allowedFiles.length <= 0) {
alert(
plural(maxMediaAttachments, {
one: 'You can only attach up to 1 file.',
other: 'You can only attach up to # files.',
}),
);
return;
}
}
const mediaFiles = allowedFiles.map((file) => ({
file,
@ -1307,8 +1328,11 @@ function Compose({
<label class="toolbar-button">
<input
type="file"
accept={supportedMimeTypes.join(',')}
multiple={mediaAttachments.length < maxMediaAttachments - 1}
accept={supportedMimeTypes?.join(',')}
multiple={
maxMediaAttachments === undefined ||
maxMediaAttachments - mediaAttachments >= 2
}
disabled={
uiState === 'loading' ||
mediaAttachments.length >= maxMediaAttachments ||
@ -1400,7 +1424,8 @@ function Compose({
class="toolbar-button gif-picker-button"
disabled={
uiState === 'loading' ||
mediaAttachments.length >= maxMediaAttachments ||
(maxMediaAttachments !== undefined &&
mediaAttachments.length >= maxMediaAttachments) ||
!!poll
}
onClick={() => {

View file

@ -13,6 +13,7 @@ export default function CustomEmoji({ staticUrl, alt, url }) {
height="16"
loading="lazy"
decoding="async"
fetchPriority="low"
/>
</picture>
);

View file

@ -17,12 +17,17 @@ function EmojiText({ text, emojis }) {
// 'g',
// );
const regex = shortcodesRegexp(emojis.map((e) => e.shortcode));
const elements = text.split(regex).map((word) => {
const elements = text.split(regex).map((word, i) => {
const emoji = emojis.find((e) => e.shortcode === word);
if (emoji) {
const { url, staticUrl } = emoji;
return (
<CustomEmoji staticUrl={staticUrl} alt={word} url={url} key={word} />
<CustomEmoji
staticUrl={staticUrl}
alt={word}
url={url}
key={word + '-' + i} // Handle >= 2 same shortcodes
/>
);
}
return word;

View file

@ -190,7 +190,7 @@ function NavMenu(props) {
<MenuLink to="/following">
<Icon icon="following" size="l" />{' '}
<span>
<Trans>Following</Trans>
<Trans id="following.title">Following</Trans>
</span>
</MenuLink>
)}

View file

@ -4,6 +4,7 @@ import { Fragment } from 'preact';
import { memo } from 'preact/compat';
import { api } from '../utils/api';
import { isFiltered } from '../utils/filters';
import shortenNumber from '../utils/shorten-number';
import states, { statusKey } from '../utils/states';
import { getCurrentAccountID } from '../utils/store-utils';
@ -451,6 +452,16 @@ function Notification({
notificationsCount > 0 && notificationsCount > sampleAccounts?.length;
const expandAccounts = diffCount ? 'remote' : 'local';
// If there's a status and filter action is 'hide', then the notification is hidden
// TODO: Handle 'warn' action one day
if (!!status?.filtered) {
const isOwnPost = status?.account?.id === currentAccount;
const filterInfo = isFiltered(status.filtered, 'notifications');
if (!isSelf && !isOwnPost && filterInfo?.action === 'hide') {
return null;
}
}
return (
<div
class={`notification notification-${type}`}

View file

@ -134,7 +134,10 @@ const fetchAccountTitle = pmem(async ({ id }) => {
export const SHORTCUTS_META = {
following: {
id: 'home',
title: (_, index) => (index === 0 ? t`Home` : t`Following`),
title: (_, index) =>
index === 0
? t`Home`
: t({ id: 'following.title', message: 'Following' }),
path: '/',
icon: 'home',
},

View file

@ -1292,6 +1292,9 @@ function Status({
</span>
</>
}
itemProps={{
className: 'danger',
}}
menuItemClassName="danger"
onClick={() => {
// const yes = confirm('Delete this post?');
@ -2785,6 +2788,8 @@ function Card({ card, selfReferential, selfAuthor, instance }) {
width={width}
height={height}
loading="lazy"
decoding="async"
fetchPriority="low"
alt={imageDescription || ''}
onError={(e) => {
try {

View file

@ -21,7 +21,7 @@
"code": "de-DE",
"nativeName": "Deutsch",
"name": "German",
"completion": 96
"completion": 95
},
{
"code": "eo-UY",
@ -57,7 +57,7 @@
"code": "fr-FR",
"nativeName": "français",
"name": "French",
"completion": 99
"completion": 98
},
{
"code": "gl-ES",
@ -87,13 +87,13 @@
"code": "kab",
"nativeName": "Taqbaylit",
"name": "Kabyle",
"completion": 100
"completion": 99
},
{
"code": "ko-KR",
"nativeName": "한국어",
"name": "Korean",
"completion": 97
"completion": 96
},
{
"code": "lt-LT",
@ -105,7 +105,7 @@
"code": "nb-NO",
"nativeName": "norsk bokmål",
"name": "Norwegian Bokmål",
"completion": 31
"completion": 37
},
{
"code": "nl-NL",

1196
src/locales/ar-SA.po generated

File diff suppressed because it is too large Load diff

1118
src/locales/ca-ES.po generated

File diff suppressed because it is too large Load diff

1196
src/locales/cs-CZ.po generated

File diff suppressed because it is too large Load diff

1196
src/locales/de-DE.po generated

File diff suppressed because it is too large Load diff

982
src/locales/en.po generated

File diff suppressed because it is too large Load diff

986
src/locales/eo-UY.po generated

File diff suppressed because it is too large Load diff

1010
src/locales/es-ES.po generated

File diff suppressed because it is too large Load diff

1084
src/locales/eu-ES.po generated

File diff suppressed because it is too large Load diff

1134
src/locales/fa-IR.po generated

File diff suppressed because it is too large Load diff

1198
src/locales/fi-FI.po generated

File diff suppressed because it is too large Load diff

1200
src/locales/fr-FR.po generated

File diff suppressed because it is too large Load diff

1200
src/locales/gl-ES.po generated

File diff suppressed because it is too large Load diff

1194
src/locales/he-IL.po generated

File diff suppressed because it is too large Load diff

1206
src/locales/it-IT.po generated

File diff suppressed because it is too large Load diff

1198
src/locales/ja-JP.po generated

File diff suppressed because it is too large Load diff

1200
src/locales/kab.po generated

File diff suppressed because it is too large Load diff

1196
src/locales/ko-KR.po generated

File diff suppressed because it is too large Load diff

984
src/locales/lt-LT.po generated

File diff suppressed because it is too large Load diff

1086
src/locales/nb-NO.po generated

File diff suppressed because it is too large Load diff

1208
src/locales/nl-NL.po generated

File diff suppressed because it is too large Load diff

1194
src/locales/oc-FR.po generated

File diff suppressed because it is too large Load diff

1202
src/locales/pl-PL.po generated

File diff suppressed because it is too large Load diff

1200
src/locales/pt-BR.po generated

File diff suppressed because it is too large Load diff

1200
src/locales/pt-PT.po generated

File diff suppressed because it is too large Load diff

1202
src/locales/ru-RU.po generated

File diff suppressed because it is too large Load diff

1194
src/locales/th-TH.po generated

File diff suppressed because it is too large Load diff

1194
src/locales/uk-UA.po generated

File diff suppressed because it is too large Load diff

1200
src/locales/zh-CN.po generated

File diff suppressed because it is too large Load diff

1194
src/locales/zh-TW.po generated

File diff suppressed because it is too large Load diff

View file

@ -17,7 +17,14 @@ import useTitle from '../utils/useTitle';
const LIMIT = 20;
function Following({ title, path, id, ...props }) {
useTitle(title || t`Following`, path || '/following');
useTitle(
title ||
t({
id: 'following.title',
message: 'Following',
}),
path || '/following',
);
const { masto, streaming, instance } = api();
const snapStates = useSnapshot(states);
const homeIterator = useRef();
@ -131,7 +138,7 @@ function Following({ title, path, id, ...props }) {
return (
<Timeline
title={title || t`Following`}
title={title || t({ id: 'following.title', message: 'Following' })}
id={id || 'following'}
emptyText={t`Nothing to see here.`}
errorText={t`Unable to load posts.`}

View file

@ -1,5 +1,7 @@
#settings-container {
background-color: var(--bg-faded-color);
/* Prevent immediate text size change affecting max width */
max-width: calc(40 * var(--current-text-size) - 50px - 16px);
}
#settings-container main h3 {

View file

@ -63,7 +63,14 @@ function Settings({ onClose }) {
// }, []);
return (
<div id="settings-container" class="sheet" tabIndex="-1">
<div
id="settings-container"
class="sheet"
tabIndex="-1"
style={{
'--current-text-size': `${currentTextSize}px`,
}}
>
{!!onClose && (
<button type="button" class="sheet-close" onClick={onClose}>
<Icon icon="x" alt={t`Close`} />

View file

@ -44,6 +44,8 @@ import useTitle from '../utils/useTitle';
import getInstanceStatusURL from './../utils/get-instance-status-url';
const { PHANPY_DEFAULT_INSTANCE: DEFAULT_INSTANCE } = import.meta.env;
const LIMIT = 40;
const SUBCOMMENTS_OPEN_ALL_LIMIT = 10;
const MAX_WEIGHT = 5;
@ -562,7 +564,10 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
useTitle(
heroDisplayName && heroContentText
? `${heroDisplayName}: "${heroContentText}"`
: t`Post`,
: t({
id: 'post.title',
message: 'Post',
}),
'/:instance?/s/:id',
);
@ -788,7 +793,14 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
not possible.
</Trans>
</p>
<Link to="/login" class="button">
<Link
to={
DEFAULT_INSTANCE
? `/login?instance=${DEFAULT_INSTANCE}&submit=1`
: '/login'
}
class="button"
>
<Trans>Log in</Trans>
</Link>
</div>
@ -1085,7 +1097,7 @@ function StatusThread({ id, closeLink = '/', instance: propInstance }) {
</>
) : (
<>
Post{' '}
<Trans id="post.title">Post</Trans>{' '}
<button
type="button"
class="ancestors-indicator light small"

View file

@ -8,7 +8,7 @@ function emojifyText(text, emojis = []) {
const { shortcode, staticUrl, url } = emoji;
text = text.replace(
new RegExp(`:${shortcode}:`, 'g'),
`<picture><source srcset="${staticUrl}" media="(prefers-reduced-motion: reduce)"></source><img class="shortcode-emoji emoji" src="${url}" alt=":${shortcode}:" width="16" height="16" loading="lazy" decoding="async" /></picture>`,
`<picture><source srcset="${staticUrl}" media="(prefers-reduced-motion: reduce)"></source><img class="shortcode-emoji emoji" src="${url}" alt=":${shortcode}:" width="16" height="16" loading="lazy" decoding="async" fetchPriority="low" /></picture>`,
);
});
// console.log(text, emojis);

View file

@ -19,20 +19,27 @@ function escapeHTML(html) {
const LINK_REGEX = /<a/i;
const HTTP_LINK_REGEX = /^https?:\/\//i;
const MENTION_REGEX = /^@[^@]+(@[^@]+)?$/g;
const HASHTAG_REGEX = /^#[^#]+$/g;
const CODE_BLOCK_REGEX = /^```[^]+```$/g;
const CODE_BLOCK_START_REGEX = /^```/g;
const CODE_BLOCK_END_REGEX = /```$/g;
const INLINE_CODE_REGEX = /`[^`]+`/g;
const MENTION_REGEX = /^@[^@]+(@[^@]+)?$/;
const HASHTAG_REGEX = /^#[^#]+$/;
const CODE_BLOCK_REGEX = /^```[^]+```$/;
const CODE_BLOCK_START_REGEX = /^```/;
const CODE_BLOCK_END_REGEX = /```$/;
const INLINE_CODE_REGEX = /`[^`]+`/;
const TWITTER_DOMAIN_REGEX = /(twitter|x)\.com/i;
const TWITTER_MENTION_REGEX = /@[a-zA-Z0-9_]+@(twitter|x)\.com/g;
const TWITTER_MENTION_REGEX = /@[a-zA-Z0-9_]+@(twitter|x)\.com/;
const TWITTER_MENTION_CAPTURE_REGEX = /(@([a-zA-Z0-9_]+)@(twitter|x)\.com)/g;
const CODE_INLINE_CAPTURE_REGEX = /(`[^]+?`)/g;
function createDOM(html, isDocumentFragment) {
const tpl = document.createElement('template');
tpl.innerHTML = html;
return isDocumentFragment ? tpl.content : tpl;
if (isDocumentFragment) {
const tpl = document.createElement('template');
tpl.innerHTML = html;
return tpl.content;
} else {
const tpl = document.createElement('div');
tpl.innerHTML = html;
return tpl;
}
}
function _enhanceContent(content, opts = {}) {
@ -110,13 +117,11 @@ function _enhanceContent(content, opts = {}) {
// ======
// Convert :shortcode: to <img />
let textNodes;
if (enhancedContent.includes(':')) {
if (enhancedContent.includes(':') && emojis?.length) {
textNodes = extractTextNodes(dom);
for (const node of textNodes) {
let html = escapeHTML(node.nodeValue);
if (emojis) {
html = emojifyText(html, emojis);
}
html = emojifyText(html, emojis);
fauxDiv.innerHTML = html;
node.replaceWith(...fauxDiv.childNodes);
}
@ -193,7 +198,7 @@ function _enhanceContent(content, opts = {}) {
for (const node of textNodes) {
let html = escapeHTML(node.nodeValue);
if (INLINE_CODE_REGEX.test(html)) {
html = html.replaceAll(/(`[^]+?`)/g, '<code>$1</code>');
html = html.replaceAll(CODE_INLINE_CAPTURE_REGEX, '<code>$1</code>');
}
fauxDiv.innerHTML = html;
// const nodes = [...fauxDiv.childNodes];

View file

@ -118,18 +118,14 @@ export function getCurrentInstance() {
// Massage these instance configurations to match the Mastodon API
// - Pleroma
function getInstanceConfiguration(instance) {
const {
configuration,
maxMediaAttachments,
maxTootChars,
pleroma,
pollLimits,
} = instance;
const { configuration, maxMediaAttachments, maxTootChars, pollLimits } =
instance;
const statuses = configuration?.statuses || {};
if (maxMediaAttachments) {
statuses.maxMediaAttachments ??= maxMediaAttachments;
}
if (maxTootChars) {
statuses.maxCharacters ??= maxTootChars;
}