diff --git a/routes/_actions/pin.js b/routes/_actions/pin.js index 0c020f7..b74a1e1 100644 --- a/routes/_actions/pin.js +++ b/routes/_actions/pin.js @@ -19,6 +19,7 @@ export async function setStatusPinnedOrUnpinned (statusId, pinned, toastOnSucces toast.say('Unpinned status') } } + store.setStatusPinned(currentInstance, statusId, pinned) await setStatusPinnedInDatabase(currentInstance, statusId, pinned) emit('updatePinnedStatuses') } catch (e) { diff --git a/routes/_components/dialog/components/StatusOptionsDialog.html b/routes/_components/dialog/components/StatusOptionsDialog.html index e927dbf..7b80f62 100644 --- a/routes/_components/dialog/components/StatusOptionsDialog.html +++ b/routes/_components/dialog/components/StatusOptionsDialog.html @@ -28,7 +28,12 @@ export default { account: ({$currentAccountProfile}) => $currentAccountProfile, verifyCredentials: ({$currentVerifyCredentials}) => $currentVerifyCredentials, statusId: ({status}) => status.id, - pinned: ({status}) => status.pinned, + pinned: ({statusId, $currentStatusModifications, status}) => { + if ($currentStatusModifications && statusId in $currentStatusModifications.pins) { + return $currentStatusModifications.pins[statusId] + } + return status.pinned + }, // // begin copypasta (StatusOptionsDialog.html / AccountProfileOptionsDialog.html) // diff --git a/routes/_store/mixins/statusMixins.js b/routes/_store/mixins/statusMixins.js index bb0e717..cf3e42c 100644 --- a/routes/_store/mixins/statusMixins.js +++ b/routes/_store/mixins/statusMixins.js @@ -2,21 +2,28 @@ function getStatusModifications (store, instanceName) { let { statusModifications } = store.get() statusModifications[instanceName] = statusModifications[instanceName] || { favorites: {}, - reblogs: {} + reblogs: {}, + pins: {} } return statusModifications } +function setStatusModification (store, instanceName, statusId, key, value) { + let statusModifications = getStatusModifications(store, instanceName) + statusModifications[instanceName][key][statusId] = value + store.set({ statusModifications }) +} + export function statusMixins (Store) { Store.prototype.setStatusFavorited = function (instanceName, statusId, favorited) { - let statusModifications = getStatusModifications(this, instanceName) - statusModifications[instanceName].favorites[statusId] = favorited - this.set({statusModifications}) + setStatusModification(this, instanceName, statusId, 'favorites', favorited) } Store.prototype.setStatusReblogged = function (instanceName, statusId, reblogged) { - let statusModifications = getStatusModifications(this, instanceName) - statusModifications[instanceName].reblogs[statusId] = reblogged - this.set({statusModifications}) + setStatusModification(this, instanceName, statusId, 'reblogs', reblogged) + } + + Store.prototype.setStatusPinned = function (instanceName, statusId, pinned) { + setStatusModification(this, instanceName, statusId, 'pins', pinned) } } diff --git a/tests/spec/117-pin-unpin.js b/tests/spec/117-pin-unpin.js index 35d3501..10c3d41 100644 --- a/tests/spec/117-pin-unpin.js +++ b/tests/spec/117-pin-unpin.js @@ -1,10 +1,14 @@ import { loginAsFoobar } from '../roles' import { - avatarInComposeBox, composeInput, getNthDialogOptionsOption, getNthPinnedStatus, getNthPinnedStatusFavoriteButton, - getNthStatus, - getNthStatusOptionsButton, getUrl, postStatusButton + avatarInComposeBox, closeDialogButton, composeInput, getNthDialogOptionsOption, getNthPinnedStatus, + getNthPinnedStatusFavoriteButton, + getNthStatus, getNthStatusContent, + getNthStatusOptionsButton, getUrl, homeNavButton, postStatusButton, scrollContainerToTop, scrollToBottomOfTimeline, + scrollToTopOfTimeline, + settingsNavButton, sleep } from '../utils' import { users } from '../users' +import { postAs } from '../serverActions' fixture`117-pin-unpin.js` .page`http://localhost:4002` @@ -49,3 +53,35 @@ test('Can favorite a pinned status', async t => { .click(getNthPinnedStatusFavoriteButton(0)) .expect(getNthPinnedStatusFavoriteButton(0).getAttribute('aria-pressed')).eql('false') }) + +test('Saved pinned/unpinned state of status', async t => { + const timeout = 20000 + await postAs('foobar', 'hey I am going to pin and unpin this') + await loginAsFoobar(t) + await t + .expect(getNthStatusContent(0).innerText).contains('hey I am going to pin and unpin this', { timeout }) + .click(getNthStatusOptionsButton(0)) + .expect(getNthDialogOptionsOption(2).innerText).contains('Pin to profile') + .click(getNthDialogOptionsOption(2)) + await sleep(1) + await t + .click(getNthStatusOptionsButton(0)) + .expect(getNthDialogOptionsOption(2).innerText).contains('Unpin from profile') + .click(closeDialogButton) + + // scroll down and back up to force an unrender + await scrollToBottomOfTimeline(t) + await scrollToTopOfTimeline(t) + await scrollContainerToTop() // otherwise the ... button is obscured by the pen button + + await t + .expect(getNthStatusContent(0).innerText).contains('hey I am going to pin and unpin this', { timeout }) + .click(getNthStatusOptionsButton(0)) + .expect(getNthDialogOptionsOption(2).innerText).contains('Unpin from profile', { timeout }) + // navigate to another page and back to force another unrender + .click(settingsNavButton) + .click(homeNavButton) + .expect(getNthStatusContent(0).innerText).contains('hey I am going to pin and unpin this', { timeout }) + .click(getNthStatusOptionsButton(0)) + .expect(getNthDialogOptionsOption(2).innerText).contains('Unpin from profile', { timeout }) +})