Merge branch 'develop' of https://codeberg.org/mkljczk/pl-fe into develop
Some checks failed
Nicolium CI / Test and upload artifacts (22.x) (push) Has been cancelled
Nicolium CI / release (push) Has been cancelled
Nicolium CI / deploy (push) Has been cancelled
pl-api CI / Test for pl-api formatting (22.x) (push) Has been cancelled
pl-hooks CI / Test for a successful build (22.x) (push) Has been cancelled

remove weird tranny shit
This commit is contained in:
2026-04-11 01:41:33 +00:00
19 changed files with 58 additions and 36 deletions

0
AGENTS.md Normal file
View File

View File

@@ -1 +1 @@
CHANGELOG.md
packages/nicolium/CHANGELOG.md

1
CLAUDE.md Symbolic link
View File

@@ -0,0 +1 @@
AGENTS.md

1
CONTRIBUTING.md Symbolic link
View File

@@ -0,0 +1 @@
docs/contributing/nicolium.md

View File

@@ -69,6 +69,8 @@ pnpm -F nicolium lint
While contributing code, try to follow the existing coding style. Common sense rules regarding contributions apply. Keep your changes focused on a single issue or feature. Do not create pull requests including larger changes you don't understand fully—whether it's from another project or some auto-generated code.
Contributions must not include LLM-generated first-party code or graphic assets.
## Localization
[React Intl](https://formatjs.github.io/docs/react-intl/) is used for localizing Nicolium. All user-visible strings, unless provided by backend, should be made translatable.

View File

@@ -45,4 +45,6 @@ The project uses [ESLint](https://eslint.org/) for code style checking. You can
pnpm -F pl-api lint
```
While contributing code, try to follow the existing coding style. Common sense rules regarding contributions apply. Keep your changes focused on a single issue or feature. Do not create pull requests including larger changes you don't understand fully—whether it's from another project or some auto-generated code.
While contributing code, try to follow the existing coding style. Common sense rules regarding contributions apply. Keep your changes focused on a single issue or feature. Do not create pull requests including larger changes you don't understand fully—whether it's from another project or some auto-generated code.
Contributions must not include LLM-generated first-party code or graphic assets.

View File

@@ -170,7 +170,7 @@ const Account = ({
const { disableUserProvidedMedia } = useSettings();
const { allowDisplayingRemoteNoLogin } = useFrontendConfig();
const withExternalLink = !allowDisplayingRemoteNoLogin && !account.local;
const withExternalLink = !me && !allowDisplayingRemoteNoLogin && account && !account.local;
const handleAction = () => {
onActionClick!(account);

View File

@@ -11,32 +11,35 @@ import type { RssFeed } from 'pl-api';
interface IRssFeedInfo {
feed: RssFeed;
timestamp: string;
url: string;
}
const RssFeedInfo: React.FC<IRssFeedInfo> = ({ feed, timestamp }) => (
const RssFeedInfo: React.FC<IRssFeedInfo> = ({ feed, timestamp, url }) => (
<div className='⁂-rss-feed-info'>
<div className='⁂-rss-feed-info__avatar'>
<Avatar src={feed.image_url || ''} size={42} alt={feed.title || ''} />
</div>
<div className='⁂-rss-feed-info__content'>
<p className='⁂-rss-feed-info__title'>{feed.title}</p>
<p className='⁂-rss-feed-info__title'>
{feed.title}
<div className='flex items-center gap-1'>
<a href={url} target='_blank' rel='noopener noreferrer' className='⁂-rss-feed-info__link'>
<RelativeTimestamp
timestamp={timestamp}
theme='muted'
size='sm'
className='whitespace-nowrap'
/>
</a>
</p>
<div className='⁂-rss-feed-info__details'>
<p>
<FormattedMessage id='rss_feed.label' defaultMessage='RSS Feed' />
</p>
<Icon src={iconRss} />
<span aria-hidden>&middot;</span>
<RelativeTimestamp
timestamp={timestamp}
theme='muted'
size='sm'
className='whitespace-nowrap'
/>
</div>
</div>
</div>

View File

@@ -545,7 +545,7 @@ const Status: React.FC<IStatus> = React.memo((props) => {
{statusInfo}
{status.rss_feed ? (
<RssFeedInfo feed={status.rss_feed} timestamp={status.created_at} />
<RssFeedInfo feed={status.rss_feed} timestamp={status.created_at} url={status.url} />
) : (
actualStatus.account_id && (
<div className='flex'>

View File

@@ -135,8 +135,8 @@ const TimelinePicker: React.FC<ITimelinePicker> = ({ active }) => {
if (
features.publicTimeline &&
(isLoggedIn
? timelineAccess.live_feeds.bubble !== 'disabled'
: timelineAccess.live_feeds.bubble === 'public')
? timelineAccess.live_feeds.remote !== 'disabled'
: timelineAccess.live_feeds.remote === 'public')
) {
items.push({
to: '/timeline/fediverse',

View File

@@ -16,7 +16,9 @@ const ProgressBar: React.FC<IProgressBar> = ({ progress, size = 'md' }) => {
const { reduceMotion } = useSettings();
const styles = useSpring({
from: { width: '0%' },
to: { width: `${Math.min(progress * 100, 100)}%` },
reset: true,
immediate: reduceMotion,
});

View File

@@ -89,7 +89,7 @@ const Slider: React.FC<ISlider> = ({
}
}
}, 60),
[node.current],
[node.current, onChange],
);
const handleKeyDown: React.KeyboardEventHandler<HTMLSpanElement> = (event) => {

View File

@@ -66,7 +66,7 @@ const StepSlider: React.FC<IStepSlider> = ({
}
}
}, 60),
[node.current],
[node.current, onChange],
);
const handleKeyDown: React.KeyboardEventHandler<HTMLSpanElement> = (event) => {

View File

@@ -101,7 +101,11 @@ const DetailedStatus: React.FC<IDetailedStatus> = ({
{renderStatusInfo()}
{actualStatus.rss_feed ? (
<RssFeedInfo feed={actualStatus.rss_feed} timestamp={actualStatus.created_at} />
<RssFeedInfo
feed={actualStatus.rss_feed}
timestamp={actualStatus.created_at}
url={actualStatus.url}
/>
) : (
<div className='mb-4'>
<Account

View File

@@ -8,7 +8,7 @@ const useTextField = (initialValue?: string) => {
const [value, setValue] = useState(initialValue);
const hasInitialValue = typeof initialValue === 'string';
const onChange: React.ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement> = (e) => {
const onChange = (e: { target: { value: string } }) => {
setValue(e.target.value);
};

View File

@@ -6,6 +6,7 @@ import { changeSetting } from '@/actions/settings';
import { useSettings } from '@/stores/settings';
import { useFeatures } from './use-features';
import { useLoggedIn } from './use-logged-in';
import type { Menu } from '@/components/dropdown-menu';
@@ -65,6 +66,7 @@ const useTimelineFiltersOptions = (
) => {
const intl = useIntl();
const features = useFeatures();
const { isLoggedIn } = useLoggedIn();
const { timelines, defaultTimeline } = useSettings();
const timelineSettings = timelines[timeline] || defaultSettings;
@@ -125,7 +127,7 @@ const useTimelineFiltersOptions = (
onChange: handleOnChecked('showNonMedia'),
});
if (timelineId) {
if (timelineId && isLoggedIn) {
items.push(null);
items.push({

View File

@@ -1810,7 +1810,7 @@
"report.unassign": "Unassign",
"report.unassign.success": "Unassigned report.",
"rss_feed.label": "RSS Feed",
"rss_feed_subscriptions.add.fail": "Failed to subsrcibe to RSS feed",
"rss_feed_subscriptions.add.fail": "Failed to subscribe to RSS feed",
"rss_feed_subscriptions.add.success": "Successfully subscribed to RSS feed",
"rss_feed_subscriptions.delete": "Delete feed",
"rss_feed_subscriptions.list.heading": "Subscribed feeds",

View File

@@ -31,7 +31,7 @@ const messages = defineMessages({
},
createFail: {
id: 'rss_feed_subscriptions.add.fail',
defaultMessage: 'Failed to subsrcibe to RSS feed',
defaultMessage: 'Failed to subscribe to RSS feed',
},
});
@@ -47,9 +47,10 @@ const NewFeedForm: React.FC = () => {
createRssFeedSubscription(url.value, {
onSuccess() {
toast.success(messages.createSuccess);
url.onChange({ target: { value: '' } });
},
onError() {
toast.success(messages.createFail);
toast.error(messages.createFail);
},
});
};
@@ -125,7 +126,9 @@ const RssFeedSubscriptions = () => {
{feed.image_url ? (
<Avatar size={40} src={feed.image_url} />
) : (
<Icon src={iconRss} size={40} />
<div className='flex size-10 items-center justify-center rounded-full rounded-lg bg-gray-200 text-gray-900 dark:bg-gray-700 dark:text-gray-100'>
<Icon src={iconRss} size={32} />
</div>
)}
<div className='flex flex-1 flex-col'>
<span>{feed.title}</span>
@@ -133,16 +136,17 @@ const RssFeedSubscriptions = () => {
{feed.url}
</Text>
</div>
<IconButton
onClick={handleDelete(feed.url)}
disabled={isPending}
className='size-8 text-gray-700 dark:text-gray-600'
src={iconX}
title={intl.formatMessage(messages.deleteFeed)}
/>
</div>
}
/>
>
<IconButton
onClick={handleDelete(feed.url)}
disabled={isPending}
className='size-8 text-gray-700 dark:text-gray-600'
src={iconX}
title={intl.formatMessage(messages.deleteFeed)}
/>
</ListItem>
))}
</List>
) : (

View File

@@ -989,10 +989,11 @@ div:has(> .⁂-timeline-status:not(.⁂-timeline-status--connected-bottom))
flex-grow: 1;
gap: 0.25rem;
align-items: center;
justify-content: space-between;
}
&__details {
@include mixins.text($theme: muted, $size: xs);
@include mixins.text($theme: muted, $size: sm);
display: flex;
gap: 0.25rem;