From c5c3962bb9aeae46d98a48e617a4de2b4927fda8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Wed, 28 Jan 2026 10:33:26 +0100 Subject: [PATCH 01/29] pl-fe: migrations from tailwind MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nicole mikołajczyk --- packages/pl-fe/src/styles/new/chats.scss | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/pl-fe/src/styles/new/chats.scss b/packages/pl-fe/src/styles/new/chats.scss index 52c61ddb4..edb43b4b3 100644 --- a/packages/pl-fe/src/styles/new/chats.scss +++ b/packages/pl-fe/src/styles/new/chats.scss @@ -83,6 +83,20 @@ } } + &__search-header { + display: flex; + align-items: center; + gap: 0.5rem; + } + + &__list { + display: flex; + flex-direction: column; + gap: 1rem; + height: 100%; + flex-grow: 1; + } + &__blankslate { display: flex; flex-direction: column; From 63a278bf6e1eac518cd2b96c00c43f952fdafd63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Fri, 30 Jan 2026 07:18:03 +0100 Subject: [PATCH 02/29] pl-fe: fix event management page layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nicole mikołajczyk --- packages/pl-fe/src/features/ui/router/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/pl-fe/src/features/ui/router/index.tsx b/packages/pl-fe/src/features/ui/router/index.tsx index 12087a923..e96aa5c18 100644 --- a/packages/pl-fe/src/features/ui/router/index.tsx +++ b/packages/pl-fe/src/features/ui/router/index.tsx @@ -743,8 +743,8 @@ export const eventInformationRoute = createRoute({ }); export const eventEditRoute = createRoute({ - getParentRoute: () => layouts.event, - path: '/edit', + getParentRoute: () => layouts.events, + path: '/@{$username}/events/$statusId/edit', component: EditEvent, beforeLoad: requireAuthMiddleware(({ context: { features } }) => { if (!features.events) throw notFound(); From c58d60a8e73184258bf21d1e049c2170bcaf1016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Fri, 30 Jan 2026 07:23:05 +0100 Subject: [PATCH 03/29] pl-fe: feedback on event participation accept/reject MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nicole mikołajczyk --- .../tabs/manage-pending-participants.tsx | 23 +++++++++++++++++-- packages/pl-fe/src/locales/en.json | 4 ++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/packages/pl-fe/src/features/compose-event/tabs/manage-pending-participants.tsx b/packages/pl-fe/src/features/compose-event/tabs/manage-pending-participants.tsx index 1f246e4ac..d008d4bd8 100644 --- a/packages/pl-fe/src/features/compose-event/tabs/manage-pending-participants.tsx +++ b/packages/pl-fe/src/features/compose-event/tabs/manage-pending-participants.tsx @@ -8,10 +8,15 @@ import Spinner from 'pl-fe/components/ui/spinner'; import Stack from 'pl-fe/components/ui/stack'; import AccountContainer from 'pl-fe/containers/account-container'; import { useAcceptEventParticipationRequestMutation, useEventParticipationRequests, useRejectEventParticipationRequestMutation } from 'pl-fe/queries/events/use-event-participation-requests'; +import toast from 'pl-fe/toast'; const messages = defineMessages({ authorize: { id: 'compose_event.participation_requests.authorize', defaultMessage: 'Authorize' }, + authorizeSuccess: { id: 'compose_event.participation_requests.authorize.success', defaultMessage: 'Event participation request authorized successfully' }, + authorizeFail: { id: 'compose_event.participation_requests.authorize.fail', defaultMessage: 'Failed to authorize event participation request' }, reject: { id: 'compose_event.participation_requests.reject', defaultMessage: 'Reject' }, + rejectSuccess: { id: 'compose_event.participation_requests.reject.success', defaultMessage: 'Event participation request rejected successfully' }, + rejectFail: { id: 'compose_event.participation_requests.reject.fail', defaultMessage: 'Failed to reject event participation request' }, }); interface IAccount { @@ -36,13 +41,27 @@ const Account: React.FC = ({ eventId, id, participationMessage }) => { theme='secondary' size='sm' text={intl.formatMessage(messages.authorize)} - onClick={() => acceptEventParticipationRequest()} + onClick={() => acceptEventParticipationRequest(undefined, { + onSuccess: () => { + toast.success(messages.authorizeSuccess); + }, + onError: () => { + toast.error(messages.authorizeFail); + }, + })} /> - )} - - onClose()} - > - {content} - - - {hasMultipleImages && ( -
+
- )} -
- - {status && ( + + )} + {status ? ( = (props) => { expandable /> - )} - - - {status && ( - - )} + ) : } + + + {status && ( + + )} ); }; diff --git a/packages/pl-fe/src/styles/components/modal.scss b/packages/pl-fe/src/styles/components/modal.scss index ed0d9a701..88cb185b0 100644 --- a/packages/pl-fe/src/styles/components/modal.scss +++ b/packages/pl-fe/src/styles/components/modal.scss @@ -1,6 +1,4 @@ -.media-modal { - touch-action: pan-y; - +.⁂-media-modal { .audio-player.detailed, .extended-video-player { @apply flex items-center justify-center; @@ -17,23 +15,4 @@ @apply max-w-full max-h-[80%]; } } - - &__closer { - display: flex; - position: absolute; - top: 0; - inset-inline-start: 0; - inset-inline-end: 0; - bottom: 0; - - > div { - flex-shrink: 0; - overflow: auto; - display: flex; - align-items: center; - justify-content: center; - width: 100%; - } - } -} - +} \ No newline at end of file diff --git a/packages/pl-fe/src/styles/new/compose.scss b/packages/pl-fe/src/styles/new/compose.scss index 3d594c99a..94176cce9 100644 --- a/packages/pl-fe/src/styles/new/compose.scss +++ b/packages/pl-fe/src/styles/new/compose.scss @@ -152,7 +152,7 @@ } } -.⁂-modal-root__modal .⁂-compose-form__select-buttons { +.⁂-modal-root__container .⁂-compose-form__select-buttons { padding-top: 0.25rem; } diff --git a/packages/pl-fe/src/styles/new/layout.scss b/packages/pl-fe/src/styles/new/layout.scss index 37180d50b..d83e044d0 100644 --- a/packages/pl-fe/src/styles/new/layout.scss +++ b/packages/pl-fe/src/styles/new/layout.scss @@ -270,25 +270,38 @@ body { @apply fixed inset-0 bg-gray-500/90 black:bg-gray-900/90 dark:bg-gray-700/90; } - &__modal { - @apply mx-auto relative pointer-events-none flex items-center; - min-height: calc(min(100vh - 3.5rem, 100dvh)); + &__container { + position: fixed; + top: 0; + inset-inline-start: 0; + width: 100%; + height: 100%; + box-sizing: border-box; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + align-content: space-around; + pointer-events: none; + user-select: none; + overscroll-behavior: none; + min-height: 100dvh; + z-index: 9999; } &[data-modal-type='DROPDOWN_MENU'] &__overlay { @apply opacity-60; } - &[data-modal-type='MEDIA'], &[data-modal-type='DROPDOWN_MENU'] { - .⁂-modal-root__modal { + &[data-modal-type='DROPDOWN_MENU'] { + .⁂-modal-root__container { margin-top: 0!important; margin-bottom: 0!important; } } - &:not([data-modal-type='MEDIA']) &__modal { + &:not([data-modal-type='MEDIA']) &__container { display: flex; - height: 100%; padding: 0 1rem; @apply md:p-0; } diff --git a/packages/pl-fe/src/styles/new/modals.scss b/packages/pl-fe/src/styles/new/modals.scss index 363a51b19..3669def3e 100644 --- a/packages/pl-fe/src/styles/new/modals.scss +++ b/packages/pl-fe/src/styles/new/modals.scss @@ -1,3 +1,5 @@ +@use 'variables'; + .⁂-crypto-donate-modal { @apply max-w-sm; } @@ -6,6 +8,72 @@ @apply max-w-4xl; } +.⁂-media-modal { + pointer-events: auto; + user-select: text; + display: flex; + max-width: 100vw; + width: 100%; + height: 100%; + position: relative; + touch-action: pan-y; + @apply bg-gray-900/90; + + &__content { + @apply flex flex-col justify-between fixed inset-0 h-full grow touch-pan-y transition-all xl:pr-96; + } + + &__closer { + display: flex; + position: absolute; + top: 0; + inset-inline-start: 0; + inset-inline-end: 0; + bottom: 0; + + @media (min-width: variables.$breakpoint-xl) { + inset-inline-end: 24rem; + } + + > div { + flex-shrink: 0; + overflow: auto; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + } + } + + &__navigation { + display: flex; + flex-direction: column; + justify-content: space-between; + position: absolute; + top: 0; + inset-inline-start: 0; + inset-inline-end: 0; + bottom: 0; + pointer-events: none; + transition: opacity .3s linear; + will-change: opacity; + + &--hidden { + opacity: 0; + } + } + + &--fullscreen { + .⁂-media-modal__content { + @apply xl:pr-0; + } + + .⁂-media-modal__closer { + inset-inline-end: 0; + } + } +} + .⁂-zoomable-image { position: relative; width: 100%; From 850bb75dc0633a87787995e9597c3d475e21edb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Fri, 6 Feb 2026 16:02:44 +0100 Subject: [PATCH 28/29] idk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nicole mikołajczyk --- packages/pl-fe/src/styles/new/modals.scss | 45 +++++++++++++++++------ 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/packages/pl-fe/src/styles/new/modals.scss b/packages/pl-fe/src/styles/new/modals.scss index 3669def3e..9ee3f40ee 100644 --- a/packages/pl-fe/src/styles/new/modals.scss +++ b/packages/pl-fe/src/styles/new/modals.scss @@ -20,7 +20,19 @@ @apply bg-gray-900/90; &__content { - @apply flex flex-col justify-between fixed inset-0 h-full grow touch-pan-y transition-all xl:pr-96; + display: flex; + flex-direction: column; + justify-content: space-between; + flex-grow: 1; + inset: 0; + height: 100%; + position: fixed; + touch-action: pan-y; + + @media (min-width: variables.$breakpoint-xl) { + padding-right: 24rem; + } + @apply transition-all; } &__closer { @@ -31,10 +43,6 @@ inset-inline-end: 0; bottom: 0; - @media (min-width: variables.$breakpoint-xl) { - inset-inline-end: 24rem; - } - > div { flex-shrink: 0; overflow: auto; @@ -63,12 +71,18 @@ } } + &__closer, &__navigation { + @media (min-width: variables.$breakpoint-xl) { + inset-inline-end: 24rem; + } + } + &--fullscreen { .⁂-media-modal__content { @apply xl:pr-0; } - .⁂-media-modal__closer { + .⁂-media-modal__closer, .⁂-media-modal__navigation { inset-inline-end: 0; } } @@ -85,11 +99,6 @@ overflow: hidden; user-select: none; - &--zoomed-in { - z-index: 9999; - cursor: grab; - } - &--error img { display: none; } @@ -107,11 +116,23 @@ } img { - @apply shadow-2xl; + max-width: 100%; max-height: 80%; width: auto; height: auto; + outline: 1px solid rgba(var(--color-gray-400) / 0.15); + outline-offset: -1px; touch-action: none; user-select: none; } + + &--zoomed-in { + // z-index: 9999; + cursor: grab; + + img { + outline: none; + border-radius: 0; + } + } } \ No newline at end of file From 8352114f210b87358024ff20235023e624ef42d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Fri, 6 Feb 2026 18:06:16 +0100 Subject: [PATCH 29/29] pl-fe: i'm so tired of working on this MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nicole mikołajczyk --- .../features/ui/components/zoomable-image.tsx | 4 +- packages/pl-fe/src/modals/media-modal.tsx | 75 +++++++++---------- 2 files changed, 37 insertions(+), 42 deletions(-) diff --git a/packages/pl-fe/src/features/ui/components/zoomable-image.tsx b/packages/pl-fe/src/features/ui/components/zoomable-image.tsx index b3ad4b55e..d35c94281 100644 --- a/packages/pl-fe/src/features/ui/components/zoomable-image.tsx +++ b/packages/pl-fe/src/features/ui/components/zoomable-image.tsx @@ -133,7 +133,7 @@ const ZoomableImage: React.FC = ({ if (value === MIN_SCALE) { onZoomChange(false); } else { - onZoomChange(true); + // onZoomChange(true); } }, }, @@ -251,7 +251,7 @@ const ZoomableImage: React.FC = ({ ); if (!zoomedIn) { - void api.start({ scale: MIN_SCALE, x: 0, y: 0 }); + // void api.start({ scale: MIN_SCALE, x: 0, y: 0 }); } else if (style.scale.get() === MIN_SCALE) { void api.start({ scale: zoomMatrixRef.current.initialScale, x: 0, y: 0 }); } diff --git a/packages/pl-fe/src/modals/media-modal.tsx b/packages/pl-fe/src/modals/media-modal.tsx index c6626c21a..347e1221d 100644 --- a/packages/pl-fe/src/modals/media-modal.tsx +++ b/packages/pl-fe/src/modals/media-modal.tsx @@ -2,7 +2,7 @@ import { animated, useSpring } from '@react-spring/web'; import { Link } from '@tanstack/react-router'; import { useDrag } from '@use-gesture/react'; import clsx from 'clsx'; -import React, { type RefCallback, useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; import { fetchStatusWithContext } from 'pl-fe/actions/statuses'; @@ -68,23 +68,20 @@ const MediaModal: React.FC = (props) => { const [wrapperStyles, api] = useSpring(() => ({ x: `-${index * 100}%`, - })); + }), [index]); - const handleChangeIndex = useCallback( - (newIndex: number, animate = false) => { - if (newIndex < 0) { - newIndex = media.length + newIndex; - } else if (newIndex >= media.length) { - newIndex = newIndex % media.length; - } - setIndex(newIndex); - setZoomedIn(false); - if (animate) { - void api.start({ x: `calc(-${newIndex * 100}% + 0px)` }); - } - }, - [api, media.length], - ); + const handleChangeIndex = useCallback((newIndex: number, animate = false) => { + if (newIndex < 0) { + newIndex = media.length + newIndex; + } else if (newIndex >= media.length) { + newIndex = newIndex % media.length; + } + setIndex(newIndex); + setZoomedIn(false); + if (animate) { + void api.start({ x: `calc(-${newIndex * 100}% + 0px)` }); + } + }, [api, media.length]); const handlePrevClick = useCallback(() => { handleChangeIndex(index - 1, true); }, [handleChangeIndex, index]); @@ -92,19 +89,19 @@ const MediaModal: React.FC = (props) => { handleChangeIndex(index + 1, true); }, [handleChangeIndex, index]); - const [viewportDimensions, setViewportDimensions] = useState<{ - width: number; - height: number; - }>({ width: 0, height: 0 }); + // const [viewportDimensions, setViewportDimensions] = useState<{ + // width: number; + // height: number; + // }>({ width: 0, height: 0 }); - const handleRef: RefCallback = useCallback((ele) => { - if (ele?.clientWidth && ele.clientHeight) { - setViewportDimensions({ - width: ele.clientWidth, - height: ele.clientHeight, - }); - } - }, []); + // const handleRef: RefCallback = useCallback((ele) => { + // if (ele?.clientWidth && ele.clientHeight) { + // setViewportDimensions({ + // width: ele.clientWidth, + // height: ele.clientHeight, + // }); + // } + // }, []); const hasMultipleImages = media.length > 1; @@ -135,7 +132,7 @@ const MediaModal: React.FC = (props) => { // Disable swipe when interacting with video/audio controls or other interactive elements const target = event?.target as HTMLElement | null; if (target) { - const interactiveParent = target.closest('.video-player__controls'); + const interactiveParent = target.closest('.video-player__controls, button'); if (interactiveParent) { cancel(); return; @@ -152,9 +149,7 @@ const MediaModal: React.FC = (props) => { } // Set the x position via calc to ensure proper centering regardless of screen size. const x = active ? mx : 0; - void api.start({ - x: `calc(-${index * 100}% + ${x}px)`, - }); + void api.start({ x: `calc(-${index * 100}% + ${x}px)` }); }, { pointer: { capture: false } }, ); @@ -168,11 +163,11 @@ const MediaModal: React.FC = (props) => { setNavigationHidden(value => !value && userTouching.matches); }; - const currentMedia = media[index]; + // const currentMedia = media[index]; - const zoomable = - currentMedia.type === 'image' && currentMedia.meta.original && - (currentMedia.meta.original.width > viewportDimensions.width || currentMedia.meta.original.height > viewportDimensions.height); + // const zoomable = + // currentMedia.type === 'image' && currentMedia.meta.original && + // (currentMedia.meta.original.width > viewportDimensions.width || currentMedia.meta.original.height > viewportDimensions.height); const handleZoomClick = useCallback(() => { setZoomedIn((prev) => !prev); @@ -297,7 +292,7 @@ const MediaModal: React.FC = (props) => { {...bind()} onClick={handleClickOutside} className='⁂-media-modal__content' - ref={handleRef} + // ref={handleRef} > = (props) => { /> - {zoomable && ( + {/* {zoomable && ( = (props) => { iconClassName='h-5 w-5' onClick={handleZoomClick} /> - )} + )} */}