diff --git a/app/fileManager.js b/app/fileManager.js index 3ab7033e..9e77aae0 100644 --- a/app/fileManager.js +++ b/app/fileManager.js @@ -5,6 +5,7 @@ import { copyToClipboard, delay, openLinksInNewTab, percent } from './utils'; import * as metrics from './metrics'; import Archive from './archive'; import { bytes } from './utils'; +import okDialog from './templates/okDialog'; export default function(state, emitter) { let lastRender = 0; @@ -95,7 +96,7 @@ export default function(state, emitter) { try { state.archive.addFiles(files, maxSize); } catch (e) { - alert( + state.modal = okDialog( state.translate(e.message, { size: bytes(maxSize), count: LIMITS.MAX_FILES_PER_ARCHIVE @@ -108,11 +109,12 @@ export default function(state, emitter) { emitter.on('upload', async ({ type, dlimit, password }) => { if (!state.archive) return; if (state.storage.files.length >= LIMITS.MAX_ARCHIVES_PER_USER) { - return alert( + state.modal = okDialog( state.translate('tooManyArchives', { count: LIMITS.MAX_ARCHIVES_PER_USER }) ); + return render(); } const size = state.archive.size; if (!state.timeLimit) state.timeLimit = DEFAULTS.EXPIRE_SECONDS; diff --git a/app/main.css b/app/main.css index afc2040b..71d87247 100644 --- a/app/main.css +++ b/app/main.css @@ -1,23 +1,25 @@ @import './base.css'; -@import './templates/activeBackground/activeBackground.css'; -@import './templates/header/header.css'; -@import './templates/downloadButton/downloadButton.css'; -@import './templates/passwordInput/passwordInput.css'; -@import './templates/downloadPassword/downloadPassword.css'; -@import './templates/setPasswordSection/setPasswordSection.css'; -@import './templates/footer/footer.css'; -@import './templates/fxPromo/fxPromo.css'; -@import './templates/selectbox/selectbox.css'; -@import './templates/fileList/fileList.css'; -@import './templates/file/file.css'; -@import './templates/uploadedFile/uploadedFile.css'; -@import './templates/uploadedFileList/uploadedFileList.css'; -@import './templates/popup/popup.css'; -@import './templates/title/title.css'; -@import './templates/fileIcon/fileIcon.css'; -@import './templates/signupPromo/signupPromo.css'; -@import './templates/userAccount/userAccount.css'; -@import './pages/welcome/welcome.css'; @import './pages/share/share.css'; @import './pages/signin/signin.css'; @import './pages/unsupported/unsupported.css'; +@import './pages/welcome/welcome.css'; +@import './templates/activeBackground/activeBackground.css'; +@import './templates/downloadButton/downloadButton.css'; +@import './templates/downloadPassword/downloadPassword.css'; +@import './templates/file/file.css'; +@import './templates/fileIcon/fileIcon.css'; +@import './templates/fileList/fileList.css'; +@import './templates/footer/footer.css'; +@import './templates/fxPromo/fxPromo.css'; +@import './templates/header/header.css'; +@import './templates/modal/modal.css'; +@import './templates/okDialog/okDialog.css'; +@import './templates/passwordInput/passwordInput.css'; +@import './templates/popup/popup.css'; +@import './templates/selectbox/selectbox.css'; +@import './templates/setPasswordSection/setPasswordSection.css'; +@import './templates/signupPromo/signupPromo.css'; +@import './templates/title/title.css'; +@import './templates/uploadedFile/uploadedFile.css'; +@import './templates/uploadedFileList/uploadedFileList.css'; +@import './templates/userAccount/userAccount.css'; diff --git a/app/main.js b/app/main.js index e13c12d8..3efb1102 100644 --- a/app/main.js +++ b/app/main.js @@ -31,6 +31,7 @@ import User from './user'; state.raven = Raven; state.user = new User(storage); window.appState = state; + window.appEmit = emitter.emit.bind(emitter); let unsupportedReason = null; if ( // Firefox < 50 diff --git a/app/routes/index.js b/app/routes/index.js index 09551cdf..d7db4a36 100644 --- a/app/routes/index.js +++ b/app/routes/index.js @@ -8,6 +8,7 @@ const signupPromo = require('../templates/signupPromo'); const activeBackground = require('../templates/activeBackground'); const fileList = require('../templates/fileList'); const profile = require('../templates/userAccount'); +const modal = require('../templates/modal'); nanotiming.disabled = true; const app = choo(); @@ -18,9 +19,16 @@ function banner(state, emit) { } } +function modalDialog(state, emit) { + if (state.modal) { + return modal(state, emit); + } +} + function body(template) { return function(state, emit) { const b = html`<body class="background ${activeBackground(state)}"> + ${modalDialog(state, emit)} ${banner(state, emit)} <main class="main"> <noscript> diff --git a/app/serviceWorker.js b/app/serviceWorker.js index a90785bc..e110487d 100644 --- a/app/serviceWorker.js +++ b/app/serviceWorker.js @@ -71,7 +71,7 @@ async function decryptStream(id) { return new Response(null, { status: 302, headers: { - Location: `/download/${id}` + Location: `/download/${id}/#${file.key}` } }); } diff --git a/app/templates/expireInfo/index.js b/app/templates/expireInfo/index.js index fa7a91b8..c9df258d 100644 --- a/app/templates/expireInfo/index.js +++ b/app/templates/expireInfo/index.js @@ -2,6 +2,7 @@ const html = require('choo/html'); const raw = require('choo/html/raw'); const selectbox = require('../selectbox'); const timeLimitText = require('../timeLimitText'); +const okDialog = require('../okDialog'); module.exports = function(state, emit) { const el = html`<div> ${raw( @@ -25,7 +26,7 @@ module.exports = function(state, emit) { value => { const max = state.user.maxDownloads; if (value > max) { - alert('todo: this setting requires an account'); + state.modal = okDialog('todo: this setting requires an account'); value = max; } state.downloadCount = value; @@ -44,7 +45,7 @@ module.exports = function(state, emit) { value => { const max = state.user.maxExpireSeconds; if (value > max) { - alert('todo: this setting requires an account'); + state.modal = okDialog('todo: this setting requires an account'); value = max; } state.timeLimit = value; diff --git a/app/templates/modal/index.js b/app/templates/modal/index.js new file mode 100644 index 00000000..94f184c3 --- /dev/null +++ b/app/templates/modal/index.js @@ -0,0 +1,15 @@ +const html = require('choo/html'); + +module.exports = function(state, emit) { + return html` + <div class="modal" onclick=${close}> + <div class="modal__box" onclick=${e => e.stopPropagation()}> + ${state.modal(state, close)} + </div> + </div>`; + + function close(event) { + state.modal = null; + emit('render'); + } +}; diff --git a/app/templates/modal/modal.css b/app/templates/modal/modal.css new file mode 100644 index 00000000..947ea39a --- /dev/null +++ b/app/templates/modal/modal.css @@ -0,0 +1,22 @@ +.modal { + display: flex; + justify-content: center; + align-items: center; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + overflow: hidden; + z-index: 100; + background: rgba(0, 0, 0, 0.7); + animation: fade-in 0.5s forwards; +} + +.modal__box { + max-width: 480px; + max-height: 300px; + background: var(--pageBGColor); + border-radius: 4px; + color: var(--textColor); +} diff --git a/app/templates/okDialog/index.js b/app/templates/okDialog/index.js new file mode 100644 index 00000000..93015ac7 --- /dev/null +++ b/app/templates/okDialog/index.js @@ -0,0 +1,13 @@ +const html = require('choo/html'); + +module.exports = function(message) { + return function(state, close) { + return html` + <div class="okDialog"> + <div class="okDialog__message">${message}</div> + <button class="btn" onclick=${close}>${state.translate( + 'okButton' + )}</button> + </div>`; + }; +}; diff --git a/app/templates/okDialog/okDialog.css b/app/templates/okDialog/okDialog.css new file mode 100644 index 00000000..b03fdfa5 --- /dev/null +++ b/app/templates/okDialog/okDialog.css @@ -0,0 +1,11 @@ +.okDialog { + display: flex; + flex-direction: column; + height: 100px; + font-weight: 400; + padding: 10px; +} + +.okDialog__message { + margin-bottom: 10px; +} diff --git a/public/locales/en-US/send.ftl b/public/locales/en-US/send.ftl index fc462745..26d94646 100644 --- a/public/locales/en-US/send.ftl +++ b/public/locales/en-US/send.ftl @@ -172,3 +172,4 @@ accountBenefitNotify = Be notified when your files are downloaded accountBenefitMore = Do a lot more! manageAccount = Manage Account logOut = Sign Out +okButton = Ok