From 5b94dd782980526ba5634f2a49b30001552d085d Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Fri, 2 Mar 2018 21:55:04 -0800 Subject: [PATCH] add ability to remove media --- routes/_actions/media.js | 12 ++++-- routes/_components/IconButton.html | 3 +- routes/_components/LoadingSpinner.html | 15 +------ routes/_components/compose/ComposeMedia.html | 19 ++++++--- .../_components/compose/ComposeToolbar.html | 6 ++- scss/global.scss | 16 +++++++ templates/2xx.html | 2 +- tests/images.js | 23 ++++++++++- tests/images/kitten1.jpg | Bin 0 -> 6658 bytes tests/images/kitten2.jpg | Bin 0 -> 10836 bytes tests/images/kitten3.jpg | Bin 0 -> 5806 bytes tests/images/kitten4.jpg | Bin 0 -> 5660 bytes tests/spec/12-compose.js | 6 --- tests/spec/13-compose-media.js | 39 ++++++++++++++++++ tests/utils.js | 17 +++++--- 15 files changed, 120 insertions(+), 38 deletions(-) create mode 100644 tests/images/kitten1.jpg create mode 100644 tests/images/kitten2.jpg create mode 100644 tests/images/kitten3.jpg create mode 100644 tests/images/kitten4.jpg create mode 100644 tests/spec/13-compose-media.js diff --git a/routes/_actions/media.js b/routes/_actions/media.js index 0c5ba9e..4cdb84a 100644 --- a/routes/_actions/media.js +++ b/routes/_actions/media.js @@ -8,12 +8,12 @@ export async function doMediaUpload (file) { store.set({uploadingMedia: true}) try { let response = await uploadMedia(instanceName, accessToken, file) - let mediaToUpload = store.get('mediaToUpload') || [] - mediaToUpload.push({ + let uploadedMedia = store.get('uploadedMedia') || [] + uploadedMedia.push({ data: response, file: file }) - store.set({ mediaToUpload }) + store.set({ uploadedMedia }) } catch (e) { console.error(e) toast.say('Failed to upload media: ' + (e.message || '')) @@ -21,3 +21,9 @@ export async function doMediaUpload (file) { store.set({uploadingMedia: false}) } } + +export function deleteMedia (i) { + let uploadedMedia = store.get('uploadedMedia') + uploadedMedia.splice(i, 1) + store.set({uploadedMedia}) +} diff --git a/routes/_components/IconButton.html b/routes/_components/IconButton.html index 3d961eb..5c854cc 100644 --- a/routes/_components/IconButton.html +++ b/routes/_components/IconButton.html @@ -64,12 +64,13 @@ export default { computed: { - computedClass: (pressable, pressed, big) => { + computedClass: (pressable, pressed, big, className) => { return [ 'icon-button', !pressable && 'not-pressable', pressed && 'pressed', big && 'big-icon', + className ].filter(identity).join(' ') } } diff --git a/routes/_components/LoadingSpinner.html b/routes/_components/LoadingSpinner.html index db495ab..5b78ff6 100644 --- a/routes/_components/LoadingSpinner.html +++ b/routes/_components/LoadingSpinner.html @@ -1,4 +1,4 @@ - @@ -7,22 +7,9 @@ \ No newline at end of file diff --git a/routes/_components/compose/ComposeMedia.html b/routes/_components/compose/ComposeMedia.html index 5de77fd..885ef25 100644 --- a/routes/_components/compose/ComposeMedia.html +++ b/routes/_components/compose/ComposeMedia.html @@ -1,10 +1,13 @@ -{{#if $mediaToUpload && $mediaToUpload.length}} -
- {{#each $mediaToUpload as media}} +{{#if $uploadedMedia && $uploadedMedia.length}} +
+ {{#each $uploadedMedia as media, i}}
{{media.file.name}}
-
@@ -87,8 +90,14 @@ \ No newline at end of file diff --git a/routes/_components/compose/ComposeToolbar.html b/routes/_components/compose/ComposeToolbar.html index 62a426f..ef6181f 100644 --- a/routes/_components/compose/ComposeToolbar.html +++ b/routes/_components/compose/ComposeToolbar.html @@ -4,9 +4,11 @@ href="#fa-smile" on:click="onEmojiClick()" /> - diff --git a/scss/global.scss b/scss/global.scss index 2b364e0..7099039 100644 --- a/scss/global.scss +++ b/scss/global.scss @@ -140,4 +140,20 @@ textarea { font-family: inherit; font-size: inherit; box-sizing: border-box; +} + +@keyframes spin { + 0% { + transform: rotate(0deg); + } + 50% { + transform: rotate(180deg); + } + 100% { + transform: rotate(360deg); + } +} + +.spin { + animation: spin 2s infinite linear; } \ No newline at end of file diff --git a/templates/2xx.html b/templates/2xx.html index f288e27..16ee342 100644 --- a/templates/2xx.html +++ b/templates/2xx.html @@ -11,7 +11,7 @@ diff --git a/tests/images.js b/tests/images.js index 4fb2573..67f7f08 100644 --- a/tests/images.js +++ b/tests/images.js @@ -1 +1,22 @@ -export const image1 = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==' +import fs from 'fs' +import path from 'path' + +export const kitten1 = { + data: fs.readFileSync(path.join(__dirname, './images/kitten1.jpg')).toString('base64'), + name: 'kitten1.jpg' +} + +export const kitten2 = { + data: fs.readFileSync(path.join(__dirname, './images/kitten2.jpg')).toString('base64'), + name: 'kitten2.jpg' +} + +export const kitten3 = { + data: fs.readFileSync(path.join(__dirname, './images/kitten3.jpg')).toString('base64'), + name: 'kitten3.jpg' +} + +export const kitten4 = { + data: fs.readFileSync(path.join(__dirname, './images/kitten4.jpg')).toString('base64'), + name: 'kitten4.jpg' +} diff --git a/tests/images/kitten1.jpg b/tests/images/kitten1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ee2304872c3c149d6696870aaef5b088845dcd40 GIT binary patch literal 6658 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 literal 0 HcmV?d00001 diff --git a/tests/images/kitten3.jpg b/tests/images/kitten3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6740d7c3abaaa0e47f33634197a0777a79d7ace0 GIT binary patch literal 5806 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 literal 0 HcmV?d00001 diff --git a/tests/spec/12-compose.js b/tests/spec/12-compose.js index f07d2ec..61eb3dc 100644 --- a/tests/spec/12-compose.js +++ b/tests/spec/12-compose.js @@ -91,9 +91,3 @@ test('inserts emoji without typing anything', async t => { .click($('button img[title=":blobpeek:"]')) .expect(composeInput.value).eql(':blobpeek: :blobpats: ') }) - -test('inserts media', async t => { - await t.useRole(foobarRole) - await uploadMedia() - await t.expect($('.compose-media:nth-child(1) img').getAttribute('alt')).eql('foo.png') -}) diff --git a/tests/spec/13-compose-media.js b/tests/spec/13-compose-media.js new file mode 100644 index 0000000..ad564e6 --- /dev/null +++ b/tests/spec/13-compose-media.js @@ -0,0 +1,39 @@ +import { Selector as $ } from 'testcafe' +import { getNthMedia, mediaButton, uploadKittenImage } from '../utils' +import { foobarRole } from '../roles' + +fixture`13-compose-media.js` + .page`http://localhost:4002` + +test('inserts media', async t => { + await t.useRole(foobarRole) + .expect(mediaButton.hasAttribute('disabled')).notOk() + await (uploadKittenImage(1)()) + await t.expect(getNthMedia(1).getAttribute('alt')).eql('kitten1.jpg') + await (uploadKittenImage(2)()) + await t.expect(getNthMedia(1).getAttribute('alt')).eql('kitten1.jpg') + .expect(getNthMedia(2).getAttribute('alt')).eql('kitten2.jpg') + .expect(mediaButton.hasAttribute('disabled')).notOk() + await (uploadKittenImage(3)()) + await t.expect(getNthMedia(1).getAttribute('alt')).eql('kitten1.jpg') + .expect(getNthMedia(2).getAttribute('alt')).eql('kitten2.jpg') + .expect(getNthMedia(3).getAttribute('alt')).eql('kitten3.jpg') + .expect(mediaButton.hasAttribute('disabled')).notOk() + await (uploadKittenImage(4)()) + await t.expect(getNthMedia(1).getAttribute('alt')).eql('kitten1.jpg') + .expect(getNthMedia(2).getAttribute('alt')).eql('kitten2.jpg') + .expect(getNthMedia(3).getAttribute('alt')).eql('kitten3.jpg') + .expect(getNthMedia(4).getAttribute('alt')).eql('kitten4.jpg') + .expect(mediaButton.getAttribute('disabled')).eql('') +}) + +test('removes media', async t => { + await t.useRole(foobarRole) + await (uploadKittenImage(1)()) + await (uploadKittenImage(2)()) + await t.expect(getNthMedia(1).getAttribute('alt')).eql('kitten1.jpg') + .expect(getNthMedia(2).getAttribute('alt')).eql('kitten2.jpg') + .click($('.compose-media:nth-child(2) .compose-media-delete-button')) + .expect(getNthMedia(2).exists).notOk() + .expect(getNthMedia(1).exists).ok() +}) diff --git a/tests/utils.js b/tests/utils.js index f21707e..5490dfa 100644 --- a/tests/utils.js +++ b/tests/utils.js @@ -15,6 +15,7 @@ export const composeInput = $('.compose-box-input') export const composeButton = $('.compose-box-button') export const composeLengthIndicator = $('.compose-box-length') export const emojiButton = $('.compose-box-toolbar button:first-child') +export const mediaButton = $('.compose-box-toolbar button:nth-child(2)') export const emailInput = $('input#user_email') export const passwordInput = $('input#user_password') export const authorizeInput = $('button[type=submit]:not(.negative)') @@ -39,16 +40,22 @@ export const getComposeSelectionStart = exec(() => composeInput().selectionStart dependencies: { composeInput } }) -export const uploadMedia = exec(() => { - let blob = blobUtils.base64StringToBlob(images.image1, 'image/png') - blob.name = 'foo.png' +export const uploadKittenImage = i => (exec(() => { + let image = images[`kitten${i}`] + let blob = blobUtils.base64StringToBlob(image.data, 'image/png') + blob.name = image.name window.__fakeFileInput(blob) }, { dependencies: { images, - blobUtils + blobUtils, + i } -}) +})) + +export function getNthMedia (n) { + return $(`.compose-media:nth-child(${n}) img`) +} export function getNthStatus (n) { return $(`div[aria-hidden="false"] > article[aria-posinset="${n}"]`)