DES-459
The font size of subtitles/excerpts in newsletters was similar to the
body font size which doesn't reflect the content hierarchy
appropriately. Also, the spacing should be adjusted to represent that
the title and the subtitle belong together.
ref
https://linear.app/tryghost/issue/ENG-1240/race-condition-when-updating-members-last-seen-at-timestamp
When members click a link in an email, Ghost updates the member's
`last_seen_at` timestamp, but it should only update the timestamp if the
member hasn't yet been seen in the current day (based on the
publication's timezone).
Currently there is a race condition present where multiple simultaneous
requests from the same member (if e.g. an email link checker is
following all links in an email) can cause the `last_seen_at` timestamp
to be updated multiple times in the same day for the same member. These
additional queries add a significant load on Ghost and its database,
which can contribute to the exhaustion of the connection pool and
eventually requests may time out.
The primary motivation for this change is to avoid that race condition
by adding a lock to the member row, checking if `last_seen_at` has
already been updated in the current day, and only updating it if it
hasn't.
Another beneficial side-effect of this change is that it avoids locking
the `labels` and `newsletters` tables, which are locked when we update
the `last_seen_at` timestamp in the `members` table currently. This
should improve Ghost's ability to handle a large influx of requests to
redirect endpoints (confirmed with load tests), which tend to happen
immediately after a publisher sends an email.
ref https://linear.app/tryghost/issue/ONC-94
- adds Sentry logging for the unsaved changes modal in Admin (tags,
members, collections)
This will let us monitor for spikes in rates so we know if a change to
Ghost has caused faulty logic in detecting dirty models.
Fixes
https://linear.app/tryghost/issue/DES-4/image-caption-size-in-email-newsletter.
There were no styles defined for captions for cards beyond the featured
image (bookmark, gallery, video), and we had no way of targeting those
captions with CSS. They are now wrapped in a div with a specific class,
which allows for more selective styling, and are styled similarly to the
caption of the featured image.
ref https://linear.app/tryghost/issue/ENG-1211
- the post slug now re-generates based on the post title for draft posts
unless manually set
- updated unit tests to be a bit more comprehensive
It's frequently the case that draft posts might have WIP titles. We
would generate a post slug based on the title and never change it, so
unless writers remembered to come back in to update it for their final
post, it could look off to readers. This should make that a bit more
intelligent.
Going forward, we will change the slug unless we expect it to be a custom slug (user-set in the side panel). If the title is cleared out and saved, we will also reset it. We will only ever automatically generate & change the slug for draft posts.
closes https://linear.app/tryghost/issue/ONC-96
- better matches Ghost's current usage
- avoids mismatch in expected data when `post_revisions` is populated in future
ref https://linear.app/tryghost/issue/ENG-661
- added a dirty check to ignore the `direction` field from the lexical
object; this is set dynamically and shouldn't be serialized, see
facebook/lexical/issues/4998
- fixed a bug where the modal wouldn't display on leaving the editor if
the post had no revisions (e.g. import); this could result in content
being saved over published content with no user action
- added Sentry logging for the modal
We would sometimes see the "Are you sure?" modal pop up when opening a
post in the editor and attempting to navigate away immediately, without
any changes to the post. This appears to be an issue with the serialized
Lexical data, which would change after loading into the editor,
resulting in the scratch and model's lexical values to differ, making
Admin think the user changed the content.
Ideally we'll see a fix upstream (or fix it ourselves). We may need to
revisit this if we experience other such situations. It's awfully
difficult to be able to set a flag saying 'the editor is done loading',
so this seems to be the best path for the moment.
Testing is difficult because we don't actually load the new Lexical editor into e2e/acceptance tests. I've added a unit test that can at least simulate the editor state changing on editor load.
no issue
- we weren't adding an `order` param to our posts/pages requests used to populate the search index which meant the default Admin API ordering was applied which isn't optimal for this use-case
- switched to ordering by `updated_at` to use a simple order that has an optimised index in the database
fixes https://linear.app/tryghost/issue/SLO-126
fixes https://linear.app/tryghost/issue/SLO-141
fixes https://linear.app/tryghost/issue/SLO-150
- during a session, posthog-js' rrweb extension can start throwing a lot
of errors. These errors do not affect the application
- similarly, ember-concurrency's task cancellation errors do not affect
the application. Task in ember-concurrency are expected to be canceled.
However, if they're cast to a Promise, they show up as unhandled Promise
rejections as Promises do not have a concept of cancellation
fixes https://linear.app/tryghost/issue/SLO-143
- in the editor, if there is a validation error on a post (e.g. the excerpt is longer than 300 chars), a validation error is rendered as a red banner error. However, when clicking on Preview, this error was bypassed
- additionally, we were throwing an undefined error when a validation error happened. This was unnecessary and caused hundreds of unhandled errors per week
We have noticed some attempts at Greek translation with no follow-up
from contributors. This is a complete translation with accurate file
naming conventions. We are native speakers and professionals.
Co-authored-by: Ryan Feigenbaum <48868107+royalfig@users.noreply.github.com>
Comprehensive, context aware, Bosnian translations for all available
strings.
Informal addressing of users (as is widely accepted in Bosnia and
Herzegovina).
Co-authored-by: Ryan Feigenbaum <48868107+royalfig@users.noreply.github.com>
ref https://linear.app/tryghost/issue/MOM-117
- `url` was missing in the results objects that we generate from the underlying search results
- updated service integration test with check for url presence
- updated service integration test to also run against the beta search
- added missing page factory to mirage setup
- updated mirage post serializer to include a uniquely identifiable URL for unpublished posts
ref https://linear.app/tryghost/issue/MOM-117
ref https://linear.app/tryghost/issue/MOM-70
- moved current search into new `search-provider` service and updated `search` service to use the provider service internally
- added `search-provider-beta` service
- uses `flexsearch` as the underlying index for each document so we have better indexing and matching compared to the naive exact-match search we had previously
- adds `excerpt` matching for posts and pages
- keeps results output the same as the original search provider
- added `internalLinkingSearchImprovements` labs flag so we can test this internally before reaching our internal linking beta testers
- updated `search` service to switch between providers based on labs flag
fixes https://linear.app/tryghost/issue/SLO-147
- removed Sentry message when the Lexical save is slow but successful
- bumped Sentry message to error level when the Lexical is slow and
fails
ref DES-347
- adjusted title and excerpt length of latest posts in emails
- as the layout is same (horizontal) on both desktop and mobile, truncateHtml() needed some update
- now maxLength is expected to be larger than maxLengthMobile, because the mobile layout isn't stacked anymore
- some spacing adjustment has been made as well