Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions openlibrary/i18n/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,20 @@ msgstr ""
msgid "Go to next section"
msgstr ""

#: Follow.html lists/list_follow.html
msgid "Follow"
msgstr ""

#: Follow.html
msgid "UnfollowFollow"
msgid "Unfollow"
msgstr ""

#: Follow.html lists/list_follow.html
msgid "Follow"
#: Follow.html
msgid "Failed to update followers. Please try again in a few moments."
msgstr ""

#: Follow.html
msgid "UnfollowFollow"
msgstr ""

#: FormatExpiry.html
Expand Down Expand Up @@ -6303,6 +6311,14 @@ msgstr ""
msgid "See all"
msgstr ""

#: lists/list_follow.html
msgid "Cover of book"
msgstr ""

#: lists/list_follow.html
msgid "Avatar of the owner of the list"
msgstr ""

#: lists/list_follow.html lists/widget.html my_books/dropdown_content.html
msgid "You"
msgstr ""
Expand Down
8 changes: 7 additions & 1 deletion openlibrary/macros/Follow.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
$def with (publisher, fid='', following=False, request_path='')

$ i18n_strings = {
$ 'follow': _('Follow'),
$ 'unfollow': _('Unfollow'),
$ 'errorMsg': _('Failed to update followers. Please try again in a few moments.')
$ }

$ subscriber = ctx.user and ctx.user.key
$ custom_request_path = request_path if request_path != '' else request.fullpath
<div>
Expand All @@ -10,7 +16,7 @@
<input type="hidden" value="$publisher" name="publisher"/>
<input type="hidden" value="$custom_request_path" name="redir_url"/>
$ css_treatment = 'delete' if following else 'primary'
<button type="submit" class="cta-btn cta-btn--$(css_treatment)">$_("Unfollow" if following else "Follow")</button>
<button type="submit" class="cta-btn cta-btn--$(css_treatment)" data-i18n="$json_encode(i18n_strings)">$_("Unfollow" if following else "Follow")</button>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<button type="submit" class="cta-btn cta-btn--$(css_treatment)" data-i18n="$json_encode(i18n_strings)">$_("Unfollow" if following else "Follow")</button>
<button type="submit" class="cta-btn cta-btn--$(css_treatment)" data-i18n="$json_encode(i18n_strings)">$(_("Unfollow") if following else _("Follow"))</button>

Somehow, this is creating a "UnfollowFollow" entry in messages.pot, here.

This should probably be fixed in a separate PR. Will open an issue after this is merged.

</form>
$else:
<a class="cta-btn cta-btn--primary" href="/account/login?redir_url=$(ctx.path)&action=follow:$(publisher)">$_("Follow")</a>
Expand Down
44 changes: 43 additions & 1 deletion openlibrary/plugins/openlibrary/js/book-page-lists.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { buildPartialsUrl } from './utils'

import { PersistentToast } from './Toast'
/**
* Initializes lazy-loading the "Lists" section of Open Library book pages.
*
Expand Down Expand Up @@ -44,6 +44,9 @@ export function initListsSection(elem) {
}
// Initialize private buttons after content is loaded
initPrivateButtonsAfterLoad(listSection)

const followForms = listSection.querySelectorAll('.follow-form');
initAsyncFollowing(followForms)
Comment on lines +48 to +49
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const followForms = listSection.querySelectorAll('.follow-form');
initAsyncFollowing(followForms)
const followForms = listSection.querySelectorAll('.follow-form');
initAsyncFollowing(followForms)

This needs to be here, as we are hydrating follow buttons that were asynchronously rendered.

We should also query the page for and hydrate follow buttons in the main index.js file. Doing so would make these buttons asynchronous throughout the site.

We'd likely also want to move the initAsyncFollowing function to a new file (maybe follows.js) and import it into this file.

})
}
})
Expand Down Expand Up @@ -81,3 +84,42 @@ async function fetchPartials(workId, editionId) {

return fetch(buildPartialsUrl('BPListsSection', params));
}

async function initAsyncFollowing(followForms) {
followForms.forEach(form => {
form.addEventListener('submit', async e => {
e.preventDefault();
const url = form.action;
const formData = new FormData(form);
const submitButton = form.querySelector('button[type=submit]')
const stateInput = form.querySelector('input[name=state]')

const isFollowRequest = stateInput.value === '0'
const i18nStrings = JSON.parse(submitButton.dataset.i18n)
submitButton.disabled = true

await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams(formData)
})
.then(resp => {
if (!resp.ok) {
throw new Error('Network response was not ok');
}
submitButton.classList.toggle('cta-btn--primary')
submitButton.classList.toggle('cta-btn--delete')
submitButton.textContent = isFollowRequest ? i18nStrings.unfollow : i18nStrings.follow
stateInput.value = isFollowRequest ? '1' : '0'
})
.catch(() => {
new PersistentToast(i18nStrings.errorMsg).show();
})
.finally(() => {
submitButton.disabled = false
});
});
});
}
8 changes: 4 additions & 4 deletions openlibrary/templates/lists/list_follow.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,20 @@
$ img_url = img_url.replace("-S.jpg", "-M.jpg")
$else:
$ img_url = '/images/icons/avatar_book-sm.png'
<img src="$img_url" loading="lazy" width="80"/>
<img src="$img_url" alt="$_('Cover of book')" loading="lazy" width="80"/>
</a>

<!-- Bottom section: owner info or community label -->
$if owner:
<div class="list-follow-card__bottom">
<div class="list-follow-card__user">

$ owner_username = owner.key.split('/')[-1]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$ owner_username = owner.key.split('/')[-1]
$ owner_username = owner.key.split('/')[-1]

<a href="$owner.key">
<img src="$(owner.key)/avatar" />
<img src="$(owner.key)/avatar" alt="$_('Avatar of the owner of the list')" />
</a>
<div class="list-follow-card__username">
$if not own_list:
$ owner_username = owner.key.split('/')[-1]
<a class="list-follow-card__username-link" href="$owner.key" title="$owner_username">
@${owner_username}
</a>
Expand All @@ -45,7 +46,6 @@
</div>
<div class="list-follow-card__follow-button">
$if not own_list:
$ owner_username = owner.key.split('/')[-1]
$ owner_account = get_user_object(owner_username)
$ is_subscribed = ctx.user and ctx.user.is_subscribed_user(owner_username)
$ settings = owner_account.get_users_settings()
Expand Down
Loading