diff --git a/routes/_components/compose/ComposeBox.html b/routes/_components/compose/ComposeBox.html index 5778228c..2f6ec31c 100644 --- a/routes/_components/compose/ComposeBox.html +++ b/routes/_components/compose/ComposeBox.html @@ -1,4 +1,4 @@ -
+
{{#if contentWarningShown}}
-
+
-
+{{#if !hideBottomBorder}} +
+{{/if}} + \ No newline at end of file diff --git a/routes/_components/status/StatusToolbar.html b/routes/_components/status/StatusToolbar.html index 89978269..c22bfeaa 100644 --- a/routes/_components/status/StatusToolbar.html +++ b/routes/_components/status/StatusToolbar.html @@ -1,8 +1,9 @@
@@ -45,17 +46,16 @@ import { registerClickDelegate, unregisterClickDelegate } from '../../_utils/delegate' import { setFavorited } from '../../_actions/favorite' import { setReblogged } from '../../_actions/reblog' - import { goto } from 'sapper/runtime.js' import { importDialogs } from '../../_utils/asyncModules' import { updateProfileAndRelationship } from '../../_actions/accounts' import { FAVORITE_ANIMATION, REBLOG_ANIMATION } from '../../_static/animations' export default { oncreate() { - registerClickDelegate(this.get('favoriteKey'), () => this.onFavoriteClick()) - registerClickDelegate(this.get('reblogKey'), () => this.onReblogClick()) - registerClickDelegate(this.get('replyKey'), () => this.onReplyClick()) - registerClickDelegate(this.get('optionsKey'), () => this.onOptionsClick()) + registerClickDelegate(this.get('favoriteKey'), (e) => this.onFavoriteClick(e)) + registerClickDelegate(this.get('reblogKey'), (e) => this.onReblogClick(e)) + registerClickDelegate(this.get('replyKey'), (e) => this.onReplyClick(e)) + registerClickDelegate(this.get('optionsKey'), (e) => this.onOptionsClick(e)) }, ondestroy() { unregisterClickDelegate(this.get('favoriteKey')) @@ -68,23 +68,36 @@ }, store: () => store, methods: { - onFavoriteClick() { + onFavoriteClick(e) { + e.preventDefault() + e.stopPropagation() let originalStatusId = this.get('originalStatusId') let favorited = this.get('favorited') /* no await */ setFavorited(originalStatusId, !favorited) this.set({animateFavorite: !favorited}) }, - onReblogClick() { + onReblogClick(e) { + e.preventDefault() + e.stopPropagation() let originalStatusId = this.get('originalStatusId') let reblogged = this.get('reblogged') /* no await */ setReblogged(originalStatusId, !reblogged) this.set({animateReblog: !reblogged}) }, - onReplyClick() { - let originalStatusId = this.get('originalStatusId') - goto(`/statuses/${originalStatusId}/reply`) + onReplyClick(e) { + e.preventDefault() + e.stopPropagation() + requestAnimationFrame(() => { + let uuid = this.get('uuid') + let $repliesShown = this.store.get('repliesShown') + $repliesShown[uuid] = !$repliesShown[uuid] + this.store.set({'repliesShown': $repliesShown}) + this.fire('recalculateHeight') + }) }, - async onOptionsClick() { + async onOptionsClick(e) { + e.preventDefault() + e.stopPropagation() let originalStatusId = this.get('originalStatusId') let originalAccountId = this.get('originalAccountId') let updateRelationshipPromise = updateProfileAndRelationship(originalAccountId) @@ -98,6 +111,7 @@ reblogAnimation: REBLOG_ANIMATION }), computed: { + replyLabel: (replyShown) => replyShown ? 'Close reply' : 'Reply', reblogLabel: (visibility) => { switch (visibility) { case 'private': diff --git a/routes/_pages/statuses/[statusId]/reply.html b/routes/_pages/statuses/[statusId]/reply.html deleted file mode 100644 index dc4c72b2..00000000 --- a/routes/_pages/statuses/[statusId]/reply.html +++ /dev/null @@ -1,44 +0,0 @@ - -
- {{#if status}} - - - {{else}} - - {{/if}} -
- - \ No newline at end of file diff --git a/routes/_store/store.js b/routes/_store/store.js index 8f20c664..ffaa7a90 100644 --- a/routes/_store/store.js +++ b/routes/_store/store.js @@ -33,6 +33,7 @@ export const store = new PinaforeStore({ instanceThemes: {}, spoilersShown: {}, sensitivesShown: {}, + repliesShown: {}, autoplayGifs: false, markMediaAsSensitive: false, reduceMotion: false, diff --git a/routes/statuses/[statusId]/reply.html b/routes/statuses/[statusId]/reply.html deleted file mode 100644 index 0a58d92c..00000000 --- a/routes/statuses/[statusId]/reply.html +++ /dev/null @@ -1,21 +0,0 @@ -<:Head> - Pinafore – Reply - - - - - \ No newline at end of file diff --git a/tests/spec/010-focus.js b/tests/spec/010-focus.js index a1adb1a6..b22d6ec7 100644 --- a/tests/spec/010-focus.js +++ b/tests/spec/010-focus.js @@ -1,6 +1,6 @@ import { getNthStatus, scrollToStatus, closeDialogButton, modalDialogContents, getActiveElementClass, goBack, getUrl, - goBackButton, getActiveElementInnerText, getNthReplyButton, getActiveElementAriaLabel, getActiveElementInsideNthStatus + goBackButton, getActiveElementInnerText, getNthReplyButton, getActiveElementInsideNthStatus } from '../utils' import { foobarRole } from '../roles' @@ -81,12 +81,5 @@ test('thread preserves focus', async t => { test('reply preserves focus and moves focus to the text input', async t => { await t.useRole(foobarRole) .click(getNthReplyButton(1)) - .expect(getUrl()).contains('/reply') .expect(getActiveElementClass()).contains('compose-box-input') - .click(goBackButton) - .expect(getUrl()).eql('http://localhost:4002/') - .expect(getNthStatus(0).exists).ok() - .expect(getActiveElementClass()).contains('icon-button') - .expect(getActiveElementAriaLabel()).eql('Reply') - .expect(getActiveElementInsideNthStatus()).eql('1') }) diff --git a/tests/spec/017-compose-reply.js b/tests/spec/017-compose-reply.js index 3b0260ff..603d9005 100644 --- a/tests/spec/017-compose-reply.js +++ b/tests/spec/017-compose-reply.js @@ -1,6 +1,7 @@ import { - composeInput, getNthReplyButton, - getNthStatus, getUrl, goBack + composeInput, + getNthComposeReplyInput, getNthReplyButton, + getNthStatus, getUrl, goBack, homeNavButton, notificationsNavButton } from '../utils' import { foobarRole } from '../roles' @@ -10,34 +11,26 @@ fixture`017-compose-reply.js` test('account handle populated correctly for replies', async t => { await t.useRole(foobarRole) .click(getNthReplyButton(0)) - .expect(getUrl()).contains('/statuses') - .expect(composeInput.value).eql('@quux ') - .typeText(composeInput, 'hello quux', {paste: true}) - .expect(composeInput.value).eql('@quux hello quux') - await goBack() - await t.click(getNthReplyButton(0)) - .expect(getUrl()).contains('/statuses') - .expect(composeInput.value).eql('@quux hello quux') - await goBack() - await t.expect(getUrl()).eql('http://localhost:4002/') + .expect(getNthComposeReplyInput(0).value).eql('@quux ') + .typeText(getNthComposeReplyInput(0), 'hello quux', {paste: true}) + .expect(getNthComposeReplyInput(0).value).eql('@quux hello quux') + .click(notificationsNavButton) + .expect(getUrl()).contains('/notifications') + .click(homeNavButton) + .expect(getUrl()).notContains('/notifications') + .expect(getNthComposeReplyInput(0).value).eql('@quux hello quux') .expect(composeInput.value).eql('') - await t.hover(getNthStatus(2)) + .hover(getNthStatus(2)) .hover(getNthStatus(4)) .click(getNthReplyButton(4)) - .expect(getUrl()).contains('/statuses') - .expect(composeInput.value).eql('') - await goBack() - await t.expect(getUrl()).eql('http://localhost:4002/') - .expect(composeInput.value).eql('') + .expect(getNthComposeReplyInput(4).value).eql('') }) test('replying to posts with mentions', async t => { await t.useRole(foobarRole) .click(getNthReplyButton(1)) - .expect(getUrl()).contains('/statuses') - .expect(composeInput.value).eql('@admin ') + .expect(getNthComposeReplyInput(1).value).eql('@admin ') .navigateTo('/accounts/4') .click(getNthReplyButton(0)) - .expect(getUrl()).contains('/statuses') - .expect(composeInput.value).eql('@ExternalLinks @admin @quux ') + .expect(getNthComposeReplyInput(0).value).eql('@ExternalLinks @admin @quux ') }) diff --git a/tests/spec/103-compose.js b/tests/spec/103-compose.js index fe89da7e..7a492462 100644 --- a/tests/spec/103-compose.js +++ b/tests/spec/103-compose.js @@ -1,6 +1,7 @@ import { foobarRole } from '../roles' import { - composeInput, getNthReplyButton, getNthStatus, getUrl, homeNavButton, notificationsNavButton, + composeInput, getNthComposeReplyButton, getNthComposeReplyInput, getNthReplyButton, getNthStatus, getUrl, + homeNavButton, notificationsNavButton, postStatusButton } from '../utils' @@ -27,10 +28,9 @@ test('statuses in threads show up in right order', async t => { .click(getNthStatus(2)) .expect(getUrl()).contains('/statuses') .click(getNthReplyButton(3)) - .expect(getUrl()).contains('/reply') - .typeText(composeInput, 'my reply!', {paste: true}) - .click(postStatusButton) - .expect(getUrl()).match(/statuses\/[^/]+$/) + .typeText(getNthComposeReplyInput(3), 'my reply!', {paste: true}) + .click(getNthComposeReplyButton(3)) + .expect(getNthComposeReplyInput(3).exists).notOk() .expect(getNthStatus(5).innerText).contains('@baz my reply!') .navigateTo('/accounts/5') .click(getNthStatus(2)) diff --git a/tests/utils.js b/tests/utils.js index 980eb275..3448e891 100644 --- a/tests/utils.js +++ b/tests/utils.js @@ -96,6 +96,14 @@ export const uploadKittenImage = i => (exec(() => { } })) +export function getNthComposeReplyInput (n) { + return getNthStatus(n).find('.compose-box-input') +} + +export function getNthComposeReplyButton (n) { + return getNthStatus(n).find('.compose-box-button') +} + export function getNthAutosuggestionResult (n) { return $(`.compose-autosuggest-list-item:nth-child(${n}) button`) }