Merge remote-tracking branch 'soapbox/develop' into events-
This commit is contained in:
commit
b7c89e502c
22 changed files with 88 additions and 65 deletions
|
@ -148,6 +148,8 @@ docker:
|
|||
image: docker:20.10.17
|
||||
services:
|
||||
- docker:20.10.17-dind
|
||||
tags:
|
||||
- dind
|
||||
# https://medium.com/devops-with-valentine/how-to-build-a-docker-image-and-push-it-to-the-gitlab-container-registry-from-a-gitlab-ci-pipeline-acac0d1f26df
|
||||
script:
|
||||
- echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB |
|
@ -6,9 +6,10 @@ import Bundle from 'soapbox/features/ui/components/bundle';
|
|||
import { MediaGallery } from 'soapbox/features/ui/util/async-components';
|
||||
|
||||
import type { List as ImmutableList } from 'immutable';
|
||||
import type { Attachment } from 'soapbox/types/entities';
|
||||
|
||||
interface IAttachmentThumbs {
|
||||
media: ImmutableList<Immutable.Record<any>>
|
||||
media: ImmutableList<Attachment>
|
||||
onClick?(): void
|
||||
sensitive?: boolean
|
||||
}
|
||||
|
@ -18,7 +19,7 @@ const AttachmentThumbs = (props: IAttachmentThumbs) => {
|
|||
const dispatch = useDispatch();
|
||||
|
||||
const renderLoading = () => <div className='media-gallery--compact' />;
|
||||
const onOpenMedia = (media: Immutable.Record<any>, index: number) => dispatch(openModal('MEDIA', { media, index }));
|
||||
const onOpenMedia = (media: ImmutableList<Attachment>, index: number) => dispatch(openModal('MEDIA', { media, index }));
|
||||
|
||||
return (
|
||||
<div className='attachment-thumbs'>
|
||||
|
@ -30,6 +31,7 @@ const AttachmentThumbs = (props: IAttachmentThumbs) => {
|
|||
height={50}
|
||||
compact
|
||||
sensitive={sensitive}
|
||||
visible
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
|
|
|
@ -263,14 +263,13 @@ const Item: React.FC<IItem> = ({
|
|||
interface IMediaGallery {
|
||||
sensitive?: boolean,
|
||||
media: ImmutableList<Attachment>,
|
||||
size: number,
|
||||
height: number,
|
||||
onOpenMedia: (media: ImmutableList<Attachment>, index: number) => void,
|
||||
defaultWidth: number,
|
||||
cacheWidth: (width: number) => void,
|
||||
defaultWidth?: number,
|
||||
cacheWidth?: (width: number) => void,
|
||||
visible?: boolean,
|
||||
onToggleVisibility?: () => void,
|
||||
displayMedia: string,
|
||||
displayMedia?: string,
|
||||
compact: boolean,
|
||||
}
|
||||
|
||||
|
@ -278,7 +277,7 @@ const MediaGallery: React.FC<IMediaGallery> = (props) => {
|
|||
const {
|
||||
media,
|
||||
sensitive = false,
|
||||
defaultWidth,
|
||||
defaultWidth = 0,
|
||||
onToggleVisibility,
|
||||
onOpenMedia,
|
||||
cacheWidth,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import classNames from 'clsx';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { useIntl, FormattedMessage } from 'react-intl';
|
||||
import { usePopper } from 'react-popper';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
|
@ -15,9 +15,10 @@ import BundleContainer from 'soapbox/features/ui/containers/bundle_container';
|
|||
import { UserPanel } from 'soapbox/features/ui/util/async-components';
|
||||
import { useAppSelector, useAppDispatch } from 'soapbox/hooks';
|
||||
import { makeGetAccount } from 'soapbox/selectors';
|
||||
import { isLocal } from 'soapbox/utils/accounts';
|
||||
|
||||
import { showProfileHoverCard } from './hover_ref_wrapper';
|
||||
import { Card, CardBody, Stack, Text } from './ui';
|
||||
import { Card, CardBody, HStack, Icon, Stack, Text } from './ui';
|
||||
|
||||
import type { AppDispatch } from 'soapbox/store';
|
||||
import type { Account } from 'soapbox/types/entities';
|
||||
|
@ -60,6 +61,7 @@ interface IProfileHoverCard {
|
|||
export const ProfileHoverCard: React.FC<IProfileHoverCard> = ({ visible = true }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const history = useHistory();
|
||||
const intl = useIntl();
|
||||
|
||||
const [popperElement, setPopperElement] = useState<HTMLElement | null>(null);
|
||||
|
||||
|
@ -88,6 +90,7 @@ export const ProfileHoverCard: React.FC<IProfileHoverCard> = ({ visible = true }
|
|||
|
||||
if (!account) return null;
|
||||
const accountBio = { __html: account.note_emojified };
|
||||
const memberSinceDate = intl.formatDate(account.created_at, { month: 'long', year: 'numeric' });
|
||||
const followedBy = me !== account.id && account.relationship?.followed_by === true;
|
||||
|
||||
return (
|
||||
|
@ -116,6 +119,23 @@ export const ProfileHoverCard: React.FC<IProfileHoverCard> = ({ visible = true }
|
|||
)}
|
||||
</BundleContainer>
|
||||
|
||||
{isLocal(account) ? (
|
||||
<HStack alignItems='center' space={0.5}>
|
||||
<Icon
|
||||
src={require('@tabler/icons/calendar.svg')}
|
||||
className='w-4 h-4 text-gray-800 dark:text-gray-200'
|
||||
/>
|
||||
|
||||
<Text size='sm'>
|
||||
<FormattedMessage
|
||||
id='account.member_since' defaultMessage='Joined {date}' values={{
|
||||
date: memberSinceDate,
|
||||
}}
|
||||
/>
|
||||
</Text>
|
||||
</HStack>
|
||||
) : null}
|
||||
|
||||
{account.source.get('note', '').length > 0 && (
|
||||
<Text size='sm' dangerouslySetInnerHTML={accountBio} />
|
||||
)}
|
||||
|
|
|
@ -376,7 +376,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
|||
menu.push({
|
||||
text: intl.formatMessage(status.pinned ? messages.unpin : messages.pin),
|
||||
action: handlePinClick,
|
||||
icon: mutingConversation ? require('@tabler/icons/pinned-off.svg') : require('@tabler/icons/pin.svg'),
|
||||
icon: status.pinned ? require('@tabler/icons/pinned-off.svg') : require('@tabler/icons/pin.svg'),
|
||||
});
|
||||
} else {
|
||||
if (status.visibility === 'private') {
|
||||
|
|
|
@ -178,6 +178,7 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chatId, chatMessageIds, a
|
|||
media={ImmutableList([attachment])}
|
||||
height={120}
|
||||
onOpenMedia={onOpenMedia}
|
||||
visible
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
|
|
|
@ -48,6 +48,7 @@ const messages = defineMessages({
|
|||
promoPanelIconsLink: { id: 'soapbox_config.hints.promo_panel_icons.link', defaultMessage: 'Soapbox Icons List' },
|
||||
authenticatedProfileLabel: { id: 'soapbox_config.authenticated_profile_label', defaultMessage: 'Profiles require authentication' },
|
||||
authenticatedProfileHint: { id: 'soapbox_config.authenticated_profile_hint', defaultMessage: 'Users must be logged-in to view replies and media on user profiles.' },
|
||||
displayCtaLabel: { id: 'soapbox_config.cta_label', defaultMessage: 'Display call to action panels if not authenticated' },
|
||||
singleUserModeLabel: { id: 'soapbox_config.single_user_mode_label', defaultMessage: 'Single user mode' },
|
||||
singleUserModeHint: { id: 'soapbox_config.single_user_mode_hint', defaultMessage: 'Front page will redirect to a given user profile.' },
|
||||
singleUserModeProfileLabel: { id: 'soapbox_config.single_user_mode_profile_label', defaultMessage: 'Main user handle' },
|
||||
|
@ -261,6 +262,13 @@ const SoapboxConfig: React.FC = () => {
|
|||
/>
|
||||
</ListItem>
|
||||
|
||||
<ListItem label={intl.formatMessage(messages.displayCtaLabel)}>
|
||||
<Toggle
|
||||
checked={soapbox.displayCta === true}
|
||||
onChange={handleChange(['displayCta'], (e) => e.target.checked)}
|
||||
/>
|
||||
</ListItem>
|
||||
|
||||
<ListItem
|
||||
label={intl.formatMessage(messages.authenticatedProfileLabel)}
|
||||
hint={intl.formatMessage(messages.authenticatedProfileHint)}
|
||||
|
|
|
@ -2,12 +2,15 @@ import React from 'react';
|
|||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Card, CardTitle, Text, Stack, Button } from 'soapbox/components/ui';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
import { useAppSelector, useSoapboxConfig } from 'soapbox/hooks';
|
||||
|
||||
/** Prompts logged-out users to log in when viewing a thread. */
|
||||
const ThreadLoginCta: React.FC = () => {
|
||||
const { displayCta } = useSoapboxConfig();
|
||||
const siteTitle = useAppSelector(state => state.instance.title);
|
||||
|
||||
if (!displayCta) return null;
|
||||
|
||||
return (
|
||||
<Card className='px-6 py-12 space-y-6 text-center' variant='rounded'>
|
||||
<Stack>
|
||||
|
|
|
@ -5,11 +5,11 @@ import { Banner, Button, HStack, Stack, Text } from 'soapbox/components/ui';
|
|||
import { useAppSelector, useSoapboxConfig } from 'soapbox/hooks';
|
||||
|
||||
const CtaBanner = () => {
|
||||
const { singleUserMode } = useSoapboxConfig();
|
||||
const { displayCta, singleUserMode } = useSoapboxConfig();
|
||||
const siteTitle = useAppSelector((state) => state.instance.title);
|
||||
const me = useAppSelector((state) => state.me);
|
||||
|
||||
if (me || singleUserMode) return null;
|
||||
if (me || !displayCta || singleUserMode) return null;
|
||||
|
||||
return (
|
||||
<div data-testid='cta-banner' className='hidden lg:block'>
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -146,10 +146,6 @@ export function ActionsModal() {
|
|||
return import(/* webpackChunkName: "features/ui" */'../components/actions_modal');
|
||||
}
|
||||
|
||||
export function FocalPointModal() {
|
||||
return import(/* webpackChunkName: "features/ui" */'../components/focal_point_modal');
|
||||
}
|
||||
|
||||
export function HotkeysModal() {
|
||||
return import(/* webpackChunkName: "features/ui" */'../components/hotkeys_modal');
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
"account.requested": "Oczekująca prośba, kliknij aby anulować",
|
||||
"account.requested_small": "Oczekująca prośba",
|
||||
"account.search": "Szukaj wpisów @{name}",
|
||||
"account.search_self": "Szukaj własnych wpisów",
|
||||
"account.share": "Udostępnij profil @{name}",
|
||||
"account.show_reblogs": "Pokazuj podbicia od @{name}",
|
||||
"account.subscribe": "Subskrybuj wpisy @{name}",
|
||||
|
@ -67,6 +68,18 @@
|
|||
"account.verified": "Zweryfikowane konto",
|
||||
"account.welcome": "Welcome",
|
||||
"account_gallery.none": "Brak zawartości multimedialnej do wyświetlenia.",
|
||||
"account_moderation_modal.admin_fe": "Otwórz w AdminFE",
|
||||
"account_moderation_modal.fields.account_role": "Poziom uprawnień",
|
||||
"account_moderation_modal.fields.badges": "Niestandaradowe odznaki",
|
||||
"account_moderation_modal.fields.deactivate": "Dezaktywuj konto",
|
||||
"account_moderation_modal.fields.delete": "Usuń konto",
|
||||
"account_moderation_modal.fields.suggested": "Proponuj obserwację tego konta",
|
||||
"account_moderation_modal.fields.verified": "Zweryfikowane konto",
|
||||
"account_moderation_modal.info.id": "ID: {id}",
|
||||
"account_moderation_modal.roles.admin": "Administrator",
|
||||
"account_moderation_modal.roles.moderator": "Moderator",
|
||||
"account_moderation_modal.roles.user": "Użytkownik",
|
||||
"account_moderation_modal.title": "Moderuj @{acct}",
|
||||
"account_note.hint": "Możesz pozostawić dla siebie notatkę o tym użytkowniku (tylko ty ją zobaczysz):",
|
||||
"account_note.placeholder": "Nie wprowadzono opisu",
|
||||
"account_note.save": "Zapisz",
|
||||
|
@ -125,6 +138,7 @@
|
|||
"admin.users.actions.unsuggest_user": "Przestań polecać @{name}",
|
||||
"admin.users.actions.unverify_user": "Cofnij weryfikację @{name}",
|
||||
"admin.users.actions.verify_user": "Weryfikuj @{name}",
|
||||
"admin.users.badges_saved_message": "Zaktualizowano niestandardowe odznaki.",
|
||||
"admin.users.remove_donor_message": "Usunięto @{acct} ze wspierających",
|
||||
"admin.users.set_donor_message": "Ustawiono @{acct} jako wspierającego",
|
||||
"admin.users.user_deactivated_message": "Zdezaktywowano @{acct}",
|
||||
|
@ -173,6 +187,7 @@
|
|||
"backups.empty_message": "Nie znaleziono kopii zapasowych. {action}",
|
||||
"backups.empty_message.action": "Chcesz utworzyć?",
|
||||
"backups.pending": "Oczekująca",
|
||||
"badge_input.placeholder": "Wprowadź odznakę…",
|
||||
"beta.also_available": "Dostępne w językach:",
|
||||
"birthday_panel.title": "Urodziny",
|
||||
"birthdays_modal.empty": "Żaden z Twoich znajomych nie ma dziś urodzin.",
|
||||
|
@ -736,8 +751,10 @@
|
|||
"migration.fields.acct.placeholder": "konto@domena",
|
||||
"migration.fields.confirm_password.label": "Obecne hasło",
|
||||
"migration.hint": "Ta opcja przeniesie Twoich obserwujących na nowe konto. Żadne inne dane nie zostaną przeniesione. Aby dokonać migracji, musisz najpierw {link} na swoim nowym koncie.",
|
||||
"migration.hint.cooldown_period": "Jeżeli przemigrujesz swoje konto, nie będziesz móc wykonać kolejnej migracji przez {cooldownPeriod, plural, one {jeden dzień} other {kolejne # dni}}.",
|
||||
"migration.hint.link": "utworzyć alias konta",
|
||||
"migration.move_account.fail": "Przenoszenie konta nie powiodło się.",
|
||||
"migration.move_account.fail.cooldown_period": "Niedawno migrowałeś(-aś) swoje konto. Spróbuj ponownie później.",
|
||||
"migration.move_account.success": "Pomyślnie przeniesiono konto.",
|
||||
"migration.submit": "Przenieś obserwujących",
|
||||
"missing_description_modal.cancel": "Anuluj",
|
||||
|
@ -747,6 +764,9 @@
|
|||
"missing_indicator.label": "Nie znaleziono",
|
||||
"missing_indicator.sublabel": "Nie można odnaleźć tego zasobu",
|
||||
"mobile.also_available": "Dostępne w językach:",
|
||||
"moderation_overlay.contact": "Kontakt",
|
||||
"moderation_overlay.hide": "Ukryj",
|
||||
"moderation_overlay.show": "Wyświetl",
|
||||
"morefollows.followers_label": "…i {count} więcej {count, plural, one {obserwujący(-a)} few {obserwujących} many {obserwujących} other {obserwujących}} na zdalnych stronach.",
|
||||
"morefollows.following_label": "…i {count} więcej {count, plural, one {obserwowany(-a)} few {obserwowanych} many {obserwowanych} other {obserwowanych}} na zdalnych stronach.",
|
||||
"mute_modal.hide_notifications": "Chcesz ukryć powiadomienia od tego użytkownika?",
|
||||
|
@ -843,6 +863,10 @@
|
|||
"onboarding.display_name.subtitle": "Możesz ją zawsze zmienić później.",
|
||||
"onboarding.display_name.title": "Wybierz wyświetlaną nazwę",
|
||||
"onboarding.done": "Gotowe",
|
||||
"onboarding.fediverse.its_you": "Oto Twoje konto! Inni ludzie mogą Cię obserwować z innych serwerów używając pełnej @nazwy.",
|
||||
"onboarding.fediverse.next": "Dalej",
|
||||
"onboarding.fediverse.title": "{siteTitle} to tylko jedna z części Fediwersum",
|
||||
"onboarding.fediverse.other_instances": "Kiedy przeglądasz oś czasum, zwróć uwagę na pełną nazwę użytkownika po znaku @, aby wiedzieć z którego serwera pochodzi wpis.",
|
||||
"onboarding.finished.message": "Cieszymy się, że możemy powitać Cię w naszej społeczności! Naciśnij poniższy przycisk, aby rozpocząć.",
|
||||
"onboarding.finished.title": "Wprowadzenie ukończone",
|
||||
"onboarding.header.subtitle": "Będzie widoczny w górnej części Twojego profilu",
|
||||
|
@ -1008,6 +1032,7 @@
|
|||
"report.target": "Zgłaszanie {target}",
|
||||
"reset_password.fail": "Token wygasł, spróbuj ponownie.",
|
||||
"reset_password.header": "Ustaw nowe hasło",
|
||||
"save": "Zapisz",
|
||||
"schedule.post_time": "Data/godzina publikacji",
|
||||
"schedule.remove": "Usuń zaplanowany wpis",
|
||||
"schedule_button.add_schedule": "Zaplanuj wpis na później",
|
||||
|
@ -1128,7 +1153,7 @@
|
|||
"sponsored.info.title": "Dlaczego widzę tę reklamę?",
|
||||
"sponsored.subtitle": "Wpis sponsorowany",
|
||||
"status.actions.more": "Więcej",
|
||||
"status.admin_account": "Otwórz interfejs moderacyjny dla @{name}",
|
||||
"status.admin_account": "Moderuj @{name}",
|
||||
"status.admin_status": "Otwórz ten wpis w interfejsie moderacyjnym",
|
||||
"status.block": "Zablokuj @{name}",
|
||||
"status.bookmark": "Dodaj do zakładek",
|
||||
|
|
|
@ -5,6 +5,8 @@ import {
|
|||
fromJS,
|
||||
} from 'immutable';
|
||||
|
||||
import { normalizeAttachment } from 'soapbox/normalizers/attachment';
|
||||
|
||||
import type { Attachment, Card, Emoji } from 'soapbox/types/entities';
|
||||
|
||||
export const ChatMessageRecord = ImmutableRecord({
|
||||
|
@ -22,8 +24,14 @@ export const ChatMessageRecord = ImmutableRecord({
|
|||
pending: false,
|
||||
});
|
||||
|
||||
const normalizeMedia = (status: ImmutableMap<string, any>) => {
|
||||
return status.update('attachment', null, normalizeAttachment);
|
||||
};
|
||||
|
||||
export const normalizeChatMessage = (chatMessage: Record<string, any>) => {
|
||||
return ChatMessageRecord(
|
||||
ImmutableMap(fromJS(chatMessage)),
|
||||
ImmutableMap(fromJS(chatMessage)).withMutations(chatMessage => {
|
||||
normalizeMedia(chatMessage);
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
|
|
@ -112,6 +112,7 @@ export const SoapboxConfigRecord = ImmutableRecord({
|
|||
singleUserModeProfile: '',
|
||||
linkFooterMessage: '',
|
||||
links: ImmutableMap<string, string>(),
|
||||
displayCta: true,
|
||||
}, 'SoapboxConfig');
|
||||
|
||||
type SoapboxConfigMap = ImmutableMap<string, any>;
|
||||
|
|
|
@ -39,7 +39,7 @@ const DefaultPage: React.FC = ({ children }) => {
|
|||
{Component => <Component limit={3} key='trends-panel' />}
|
||||
</BundleContainer>
|
||||
)}
|
||||
{features.suggestions && (
|
||||
{me && features.suggestions && (
|
||||
<BundleContainer fetchComponent={WhoToFollowPanel}>
|
||||
{Component => <Component limit={3} key='wtf-panel' />}
|
||||
</BundleContainer>
|
||||
|
|
|
@ -103,7 +103,7 @@ const HomePage: React.FC = ({ children }) => {
|
|||
{Component => <Component limit={10} />}
|
||||
</BundleContainer>
|
||||
)}
|
||||
{features.suggestions && (
|
||||
{me && features.suggestions && (
|
||||
<BundleContainer fetchComponent={WhoToFollowPanel}>
|
||||
{Component => <Component limit={3} />}
|
||||
</BundleContainer>
|
||||
|
|
|
@ -137,7 +137,7 @@ const ProfilePage: React.FC<IProfilePage> = ({ params, children }) => {
|
|||
<BundleContainer fetchComponent={PinnedAccountsPanel}>
|
||||
{Component => <Component account={account} limit={5} key='pinned-accounts-panel' />}
|
||||
</BundleContainer>
|
||||
) : features.suggestions && (
|
||||
) : me && features.suggestions && (
|
||||
<BundleContainer fetchComponent={WhoToFollowPanel}>
|
||||
{Component => <Component limit={3} key='wtf-panel' />}
|
||||
</BundleContainer>
|
||||
|
|
|
@ -43,7 +43,7 @@ const StatusPage: React.FC<IStatusPage> = ({ children }) => {
|
|||
{Component => <Component limit={3} key='trends-panel' />}
|
||||
</BundleContainer>
|
||||
)}
|
||||
{features.suggestions && (
|
||||
{me && features.suggestions && (
|
||||
<BundleContainer fetchComponent={WhoToFollowPanel}>
|
||||
{Component => <Component limit={3} key='wtf-panel' />}
|
||||
</BundleContainer>
|
||||
|
|
|
@ -242,39 +242,3 @@
|
|||
@apply block shadow-md;
|
||||
}
|
||||
}
|
||||
|
||||
.focal-point {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
|
||||
&.dragging {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 80vw;
|
||||
max-height: 80vh;
|
||||
width: auto;
|
||||
height: auto;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
&__reticle {
|
||||
position: absolute;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
transform: translate(-50%, -50%);
|
||||
background: url('../images/reticle.png') no-repeat 0 0;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 0 9999em rgba($base-shadow-color, 0.35);
|
||||
}
|
||||
|
||||
&__overlay {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -387,12 +387,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.focal-point-modal {
|
||||
max-width: 80vw;
|
||||
max-height: 80vh;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.column-inline-form {
|
||||
padding: 7px 15px;
|
||||
padding-right: 5px;
|
||||
|
|
Loading…
Reference in a new issue