no ref
Expose (some) Portal error strings for translations
💩This is a somewhat hacky (but test-passing and individual inspection
passing) solution to the way Portal handles errors. Or rather, the
half-dozen ways Portal handles errors.
Passing 't' around with context and state, and occasionally recreating
it from the site object. Yes, I am also somewhat horrified, but a better
implementation will need a major rewrite of Portal.
Addresses errors in both the popover React app and in the
data-attributes.
There are probably more. Since Portal exposes raw API responses in some
places, it's hard to enumerate everything that /might/ end up being
client-facing, but at least I've gotten the ones that I've commonly
seen.
Improvements very welcome.
no ref
- this caused some troubles with error representation and changed
defaulting behavior
Going back to the drawing board on this one. I've been working on a
larger scale refactor so that this could be a hook, which feels much
more appropriate, though a much more substantial change.
no ref
- Portal was not set up in a way to allow for easy use of the i18n
module for errors, as they weren't a React component
- moved away from the class model to a functional component that could
utilize React state (AppContext)
I'm working on a different refactor that would convert more of Portal to
hooks & functional components so that the codebase is more consistent
and easier to read. This will have to work for the moment while that is
being done, as that's no small task.
no ref
- added dir prop, calculated by i18next from language (using the dir
function)
- tweaked a few styles to use me/ms/pe/ps instead of mr/ml/pr/pl
- added updated test that checks that stemming works in English, and added tests for partial and full-word searching with RTL content.
no ref
According to the flexsearch documentation, https://github.com/nextapps-de/flexsearch?tab=readme-ov-file#cjk-word-break-chinese-japanese-korean for searching CJK text, need to pass in a custom encode function for better search results.
This enhancement for CJK will only take effect when the ghost site locale is set to one of `zh`, `zh-Hans`, `zh-Hant`, `ja`, `ko`.
Co-authored-by: Cathy Sarisky <42299862+cathysarisky@users.noreply.github.com>
REF PLG-225
- When editing a comment, the form was not aligned correctly.
- The form has more height by default now even when not focused, to
increase engagement.
REF PLG-225
- Updated placeholder text color to work in dark mode
- Fixed spacing for reply input field
- Changed comment input field styles
- Changed left border width from 3px to 1px
- Updated "Expertise" modal typography
- Updated CTA typography
closes https://linear.app/tryghost/issue/PLG-221
- added `toggleParentReplyMode()` to comment component's props so clicking Reply on a reply opens the reply form on the top-level parent to emphasise we only support 1-level deep replies and avoid unexpected nesting
- adjusted conditional so "Reply" button is shown in `<CommentMenu>` when a parent is present (behind labs flag)
- updated `useLabs()` to always return an object so we don't need to add nullish checks everywhere
# Conflicts:
# apps/comments-ui/test/e2e/actions.test.ts
no issue
- a change in browser version/dependency versions/playwright/something else has made this test flaky because the reply editor form loses focus when the expertise field gains focus (this doesn't happen in the browser) meaning when we get to our assertions the elements we care about are missing
- forcing focus back puts us into a known state for our assertions
- these apps don't need to be published because they're internal and get
compiled into Admin
- therefore, we can reset their versions back to 0.0.0 and remove the
publishConfig block so we don't accidentally publish them
closes https://linear.app/tryghost/issue/AP-421
This makes loading the inbox and activity tabs _way_ faster, so we no
longer have to artificially restrict the amount of data coming in, it
also gives us proper pagination for both views.
ref https://github.com/TryGhost/Ghost/issues/16628
This adds translation support to search, which should be the last missing piece of i18n support for Ghost's frontend 🎉
- Translation (t) helper added to sodo-search.
- Ghost head tweaked to include data-locale.
- All (I hope) strings in sodo-search wrapped in the t helper.
- Possibly poor-quality French translation strings added.
---------
Co-authored-by: Vikas Potluri <vikaspotluri123.github@gmail.com>
closes https://linear.app/tryghost/issue/AP-422
We found that some images will 403 when hotlinked, showing broken images, we
can catch these errors and render the default instead.
refs
[TryGhost/ActivityPub#44](https://github.com/TryGhost/ActivityPub/pull/44)
To support pagination in the activitypub app, the following changes have
been made:
- Move filtering and sorting of activities to the server
- Refactor how comments are processed (comments are now returned as part
of the activity)
- Refactor how replies to own activities are processed in the activities
tab (removed object map)
REF PLG-226
- Changed title copy from "You want to report this comment?" to "Report
this comment?"
- Changed button copy from "Report this comment" to "Report"
- Updated styles to be more responsive
ref https://linear.app/tryghost/issue/ENG-1570
- for a Ghost site hosted on a subdirectory, e.g. `/blog/`, adding a
navigation link to `/blog/page/` was being re-written as `/page/` in Admin settings
- fixed the underlying `formatUrl` utility function and added unit tests
ref https://linear.app/tryghost/issue/AP-395
This is a stopgap solution, because currently we don't have any of our own
reply data in the frontend, so this will show the new reply, but it won't be
present on page reload. Should be enough for a demo video, but I think we need
to either fetch our outbox, or make a new replies endpoint and fetch from there
ref b9d02f8051beb9120a282bcbf0f70440c2a3c39e
Because we disabled the button on blue of the textarea, it was being disabled
before the click would be handled! Using the mousedown event means that our
event gets handled before the blur.
ref https://linear.app/tryghost/issue/AP-396
We need to use a number instead of boolean here so that the state is always
refreshed, otherwise we can run into issues where we set `focused` to true but
there's no rerender because it was previously set to true, but unfocused
ref https://linear.app/tryghost/issue/AP-398
This adds an internal focus state so that we can render the reply box different
based on whether or not the textarea is focused!
ref https://linear.app/tryghost/issue/AP-396
I think it's nicer API to pass in a focused property, rather than an
element ref, but I don't have much experience here, so it might be the
wrong approach!
ref https://linear.app/tryghost/issue/AP-397
I think we're gonna want to pass this data into the component long
term, but this will do for now, I'm going to look at cleaning up these
components in my next B week
ref https://linear.app/tryghost/issue/ENG-1466
ref https://linear.app/tryghost/issue/ENG-1484
- Previously, filtering members with multiple "Unsubscribed from
newsletter x" led to no filtering at all, all members were returned
- This was caused by a bug in NQL, that is fixed in version 0.12.5, cf.
[commit](dd18d1d6ca)
- We're also removing the safeguard in the product around bulk deletion
when multiple newsletter filters are in use, as the root problem has
been fixed
In order to show replies in our notifications, we loop through all the
replies in our inbox, and filter them by the ones replying to an account
on our domain, however the check we were doing was on the admin domain -
which is sometimes the same as the frontend domain, but not always. This
fixes the check so that we check the frontend domain, which is the one
used by activitypub.
Pulled out the logic of finding the attachment(s) into a shared
function, which will only return an array if there are multiple
attachments, otherwise either null or an object will be returned.
This fixes an issue where the code assumed that an array meant
we have multiple attachments
refs https://linear.app/tryghost/issue/AP-388
The attributedTo property of objects refers to the author of the object,
wheras the actor of an activity refers to the author of the activity -
in the case of a `Create` activity - these are generally the same, but
in the case of an `Announce` they are different, the author refers to
the "announcer" and the attributedTo the author of the content! This is
a quick patch to use the true author when it's available, and in a
format we can handle.
- Added activity icon for Replies
- Updated Replies design
- Updated hard-coded Profile values to more realistic ones
- Renamed ActivityPub nav item and moved it to the top of the navbar
- Added a check for post attachments
ref PLG-229
- Previously we had no way of using Ghost labs flags in Comments UI.
- With this change, we now get Labs data from the existing content
settings endpoint.
- Additionally, we have a `useLabs` hook that can be accessed from
anywhere in the App to put those awesome new features behind a flag
for staging
- And we can pass labs params to the initialiser for testing.
For more details: https://ghost.slack.com/archives/C06TQR9SHSM/p1726133527960489
This gives us some live-ness in the frontend, so that when you unlike an item
in the liked view - it will be removed from the list, and the count will be
updated.
We can reuse the FeedItem here, and I've defaulted to the 'feed' layout - I'm
not 100% sure if that's correct.
The liked collection doesn't have `liked` properties, and it's a little tricky
to add on the backend with how fedify works - so for now we hardcode the
`liked` property to true, which we can do because we're rendering all of the
liked content!
We don't want our components littered with fetch calls, as it makes it
difficult to test. Instead we move our http api code into the ActivityPubAPI,
giving us a central place for adding authentication and tests in the future.
We also make sure that the components use a react query wrapped call - so that
we can take advantage of the query invalidation.
no issue
- Previously we weren't running the type checks in the
`admin-x-design-system` in CI, because we only run `yarn test:unit` in
CI. This adds the typechecks to the `yarn test:unit` command so CI will
fail if the type checks fail.
- Moved engagement stats to a reusable component
- Moved functions from Profile to a separate file
- Fixed Following on Your Profile and moved them from
modals to tabs
no issue
Give your audience a simple way to support your work with one-time payments, no membership required.
- cleaned up `tipsAndDonations` labs flag
ref https://linear.app/tryghost/issue/DEV-20/faster-builds
- we can save 75KB by using a tree-shaking import for validator
- import string comes from validator docs
- also adds validator import, which was missing for this package
closes https://linear.app/tryghost/issue/PLG-190
- often when adding portal links to your own site pages the URLs are added as absolute on the site's homepage due to copy+paste from displayed URLs in Admin
- when clicking absolute portal URLs the homepage is first loaded before the Portal popup is shown resulting in a slower and flashier experience
- added a transform for all local portal URLs on the page when Portal is initialized so links open the Portal popup immediately on the current page
ref https://linear.app/tryghost/issue/DEV-20/faster-builds
- we added concurrently because, in theory, it should make builds faster
by utilizing more cores
- however, when combined with Nx, it seems that we are trying to exceed
the number of cores, which actually makes individual builds slower
- I've removed concurrently from the apps, which should improve the
build time significantly
ref DES-706
* After a user publishes or schedules a post, they are directed to the post list
* If a post is sent as an email, they are directed to the Analytics page
* In both cases, a confirmation modal is shown
* If a post is published, they can share it directly from the confirmation modal
* Added a "Share" button and some additional functions (view, edit, and delete post) to
published posts in post analytics
* Added a manual "Refresh" button to post analytics so that there is
no need to reload the whole app to update the data
---------
Co-authored-by: Sag <guptazy@gmail.com>
- we added NestJS to Ghost as a way forwards for a new framework within
Ghost but we haven't added much to it
- requiring all the NestJS code adds about 6-9% to our boot time, so if
we're not using it, it's just time we're burning for no benefit
- for now, I've gated this behind an env var to prevent it from loading
- we can't use labs flags in the boot process, so I've gone for an env
var
no issue
- when redirecting from Stripe back to Ghost after making a donation the URL contained a double slash (`//#/portal/...`) which triggered browser security errors when Portal modified the browser history stack when navigating
- the above could prevent the donation success modal from closing
no issue
- The type checks for `admin-x-design-system` were failing for me locally for a Storybook story. It looks like we changed the `PopoverPosition` type to use 'start'/'end' rather than 'left'/'right', but this story was still using 'left'. This was causing `yarn test` to fail in the `admin-x-design-system` app.
- This commit updates the story to use 'start' instead of 'left', which allows the type checks to pass.
ref DES-755
- a direct child of a form control primitive should be a form element
- for TextField component, a div was the direct child
- this moves the input element to the form control primitive
ref INC-97
ref https://github.com/TryGhost/Ghost/issues/20767
- finishes wiring up the honeypot fied
- updates state handing to properly set the value
- maintains honeypot field across page changes within portal
There isn't a single previous commit to point to here since they didn't
get squashed. We added a honeypot field to help mitigate bot signup
activity. It's hidden, and if filled out, we can anticipate it's a bot.
Right now this just logs to Ghost while we collect data.
ref KTLO-1
These tokens should prevent untargeted attacks, as the magic link
endpoint needs a token that was generated by the server, similar to a
CSRF token, but without needing any server-side state, or a cookie to
be set for unauthenticated users.
closes https://linear.app/tryghost/issue/PLG-178
- updated conditional to ensure we're ready for GA by showing when Stripe is enabled rather than only when the feature flag is enabled
closes https://linear.app/tryghost/issue/PLG-156
- updated all default fixtures to use `500` ($5) as the default suggested donation value
- added migration to update existing settings using the old default of `0` to `500`
- this is fine to apply because the feature hasn't been released so there's no explicit `0` values in the wild
- added an acceptance test for the adminx-settings tips & donations section
AP-348
ATM the top navigation and the article drawer components are missing for
ActivityPub UI. They are both part of the next phase so we need to add
them.
closes https://linear.app/tryghost/issue/PLG-15
- removed `internalLinking` GA labs flag
- renamed search providers to `flex` and `basic`
- keeps old search provider around as it can handle non-English languages unlike the faster flex provider
- updated `search` service to switch from `flex` to `basic` when the site's locale is not english
- bumped Koenig packages to switch from a feature flag for toggling internal linking features to the presence of the `searchLinks` function in card config
- updated tests to correctly switch between flex and basic providers in respective suites
ref ONC-225
- Wires up the `editor_default_email_recipients` key to the settings
public / content api endpoint.
- This key is then wired up to Portal to determine whether it's hiding or
showing the Member subscribe toggle
- Announced (reposted) Notes show information about both the Actor that
created the Note, and the Actor that Announced it
- The content of notes now keeps the formatting and links are clickable
and shown in different color
Co-authored-by: Djordje Vlaisavljevic <dzvlais@gmail.com>
- Announced (reposted) Notes show information about both the Actor that
created the Note, and the Actor that Announced it
- The content of notes now keeps the formatting and links are clickable
and shown in different color
fixes
https://linear.app/tryghost/issue/DES-81/misleading-hardcoded-tier-preview-title-colors
Tiers and Offers in Admin were shown with hardcoded pink titles. This
changes that. They are now shown with black titles, and only in the preview will they render with the site's accent colour.
---------
Co-authored-by: Princi Vershwal <vershwal.princi@gmail.com>
no refs
Refactorings include:
- Formatting JSX to be more readable
- Filtering activities before rendering
- Fixing invalid inbox empty state HTML (nesting div inside ul)
- Adding initial support for announce activities in the inbox
ref https://linear.app/tryghost/issue/DES-591
- finished wiring up the darkMode prop through the context providers
The main impact here was that the formatting toolbar was not respecting
the dark mode settings.
Fedify will not use an array for the `items` key of collections when
there is only a single item, which wasn't being handled in our
activitypub api module.
Now we always return an array so that the components recieve consistent
data.
- Added logic for displaying different attachments for Mastodon Notes
(images, audio, video)
- Centered the feed on the screen for better focus and made the Feed
layout the default one
- Moved Following and Followers counters to the new “Profile” tab
---------
Co-authored-by: Fabien O'Carroll <fabien@allou.is>
ref https://linear.app/tryghost/issue/ENG-1464
- added redirect to sign in page when trying to access newsletter
management
If a user tries to access newsletter management when not logged in,
Portal requires sign in via magic link. This magic link didn't previous
redirect the user back to newsletter management, requiring some extra
clicks.
fix https://linear.app/tryghost/issue/SLO-190/error-no-dispatch-method-detected-did-you-embed-your-app-with
- we've spuriously been seeing `No dispatch method detected, did you
embed your app with NiceModal.Provider` when browsing to a URL that
loads a modal in Safari
- it looks like DesignSystemProvider (via DesignSystemApp) contains the
NiceModal.Provider, but this is loaded within the RoutingProvider that
could trigger a modal to load
- I tried switching around RoutingProvider and DesignSystemApp but many
other tests failed, so my fix here is to add a NiceModal.Provider to
wrap the RoutingProvider
- unfortunately, this bug is flaky to occur and I've only been able to
reproduce it on Safari, so writing a test for this would be very
tricky
no ref
- while reviewing the newsletter flows, it was apparent that we were
missing test coverage
Some of the tests in Portal are a bit redundant with tests added for
child components, but it didn't seem worth removing them after getting
them to work. There was a bug in our Portal fixture data that requires a
few changes, as well as some small adjustments for making tests easier
(testing-lib-react has `getByTestId` and simply a `querySelector` to use
alternate test attributes).
REF MOM-315
- Changed to column layout
- Fixed broken currency dropdown
- Included a link to Stripe terms & conditions
- Renamed from "Tips or donations" to "Tips & donations"
This is a bit of a stopgap, we'll want to eventually pull these hooks out into
a shared file, but for now this is fine.
This almost decouples us from admin-x-framework, but we're still using it to
get the site url as well as some types that we can pull out later.
ref https://linear.app/tryghost/issue/MOM-288
Instead of having all of our network code inside of admin-x-framework, we're
moving it into activitypub to make it easier to work with. We've also added
support for using identity tokens for authentication with the ActivityPub API.
ref https://linear.app/tryghost/issue/ENG-1433/
- in the tiers details modal, if a tier was deleted after being moved it
would crash admin
The SortableList component calls renderItem for the drag overlay on the
dragged item. However, if that item was deleted, the draggingId never
got reset causing the drag overlay to try to call renderItem on a
nonexistent item.
As a note, we don't actually use this overlay... it could be best to
strip it out to prevent causing issues.