add floating compose button
This commit is contained in:
parent
62c82a05c0
commit
58b700788c
|
@ -31,5 +31,6 @@ module.exports = [
|
|||
{id: 'fa-exclamation-triangle', src: 'node_modules/font-awesome-svg-png/white/svg/exclamation-triangle.svg', title: 'Content warning'},
|
||||
{id: 'fa-check', src: 'node_modules/font-awesome-svg-png/white/svg/check.svg', title: 'Check'},
|
||||
{id: 'fa-trash', src: 'node_modules/font-awesome-svg-png/white/svg/trash-o.svg', title: 'Delete'},
|
||||
{id: 'fa-hourglass', src: 'node_modules/font-awesome-svg-png/white/svg/hourglass.svg', title: 'Follow requested'}
|
||||
{id: 'fa-hourglass', src: 'node_modules/font-awesome-svg-png/white/svg/hourglass.svg', title: 'Follow requested'},
|
||||
{id: 'fa-pencil', src: 'node_modules/font-awesome-svg-png/white/svg/pencil.svg', title: 'Compose'}
|
||||
]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="compose-box {{overLimit ? 'over-char-limit' : ''}}">
|
||||
<div class="compose-box {{overLimit ? 'over-char-limit' : ''}} {{realm === 'dialog' ? 'dialog-size' : '' }}">
|
||||
<ComposeAuthor />
|
||||
{{#if contentWarningShown}}
|
||||
<div class="compose-content-warning-wrapper"
|
||||
|
@ -11,12 +11,16 @@
|
|||
<ComposeToolbar :realm :postPrivacy :media :contentWarningShown :text />
|
||||
<ComposeLengthIndicator :length :overLimit />
|
||||
<ComposeMedia :realm :media />
|
||||
<ComposeButton :length :overLimit on:click="onClickPostButton()" />
|
||||
</div>
|
||||
<div class="compose-box-button-sentinel" ref:sentinel></div>
|
||||
<div class="compose-box-button-wrapper" >
|
||||
<ComposeButton :length :overLimit :sticky on:click="onClickPostButton()" />
|
||||
</div>
|
||||
<div class="compose-box-border-bottom"></div>
|
||||
<style>
|
||||
.compose-box {
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
padding: 20px 20px 0 20px;
|
||||
display: grid;
|
||||
align-items: flex-start;
|
||||
grid-template-areas:
|
||||
|
@ -25,24 +29,50 @@
|
|||
"avatar input input input"
|
||||
"avatar gauge gauge gauge"
|
||||
"avatar toolbar toolbar length"
|
||||
"avatar media media media"
|
||||
"avatar button button button";
|
||||
"avatar media media media";
|
||||
grid-template-columns: min-content minmax(0, max-content) 1fr 1fr;
|
||||
border-bottom: 1px solid var(--main-border);
|
||||
width: 560px;
|
||||
max-width: calc(100vw - 40px);
|
||||
}
|
||||
|
||||
.compose-box.dialog-size {
|
||||
width: 540px;
|
||||
max-width: calc(100vw - 80px);
|
||||
}
|
||||
|
||||
.compose-box-border-bottom {
|
||||
height: 1px;
|
||||
background: var(--main-border);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.compose-box-button-wrapper {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
top: 10px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.compose-content-warning-wrapper {
|
||||
grid-area: cw;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.compose-box {
|
||||
padding: 10px 10px;
|
||||
padding: 10px 10px 0 10px;
|
||||
max-width: calc(100vw - 20px);
|
||||
width: 580px;
|
||||
}
|
||||
.compose-box.dialog-size {
|
||||
width: 560px;
|
||||
max-width: calc(100vw - 40px);
|
||||
}
|
||||
.compose-box-button-wrapper {
|
||||
top: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
|
@ -59,20 +89,35 @@
|
|||
import { store } from '../../_store/store'
|
||||
import { slide } from 'svelte-transitions'
|
||||
import { postStatus, insertHandleForReply } from '../../_actions/compose'
|
||||
import { importDialogs } from '../../_utils/asyncModules'
|
||||
|
||||
export default {
|
||||
oncreate() {
|
||||
let realm = this.get('realm')
|
||||
if (realm !== 'home') {
|
||||
if (realm === 'home') {
|
||||
this.__stickyObserver = new IntersectionObserver(entries => {
|
||||
this.set({sticky: !entries[0].isIntersecting})
|
||||
})
|
||||
this.__stickyObserver.observe(this.refs.sentinel)
|
||||
} else if (realm !== 'dialog') {
|
||||
// if this is a reply, populate the handle immediately
|
||||
insertHandleForReply(realm)
|
||||
}
|
||||
|
||||
this.observe('postedStatusForRealm', postedStatusForRealm => {
|
||||
if (postedStatusForRealm !== realm) {
|
||||
return
|
||||
}
|
||||
this.fire('postedStatus')
|
||||
// if this is a reply, go back immediately after it's posted
|
||||
this.observe('postedStatusForRealm', postedStatusForRealm => {
|
||||
if (postedStatusForRealm === realm) {
|
||||
window.history.back()
|
||||
}
|
||||
}, {init: false})
|
||||
if (realm !== 'home' && realm !== 'dialog') {
|
||||
window.history.back()
|
||||
}
|
||||
}, {init: false})
|
||||
},
|
||||
ondestroy() {
|
||||
if (this.__stickyObserver) {
|
||||
this.__stickyObserver.disconnect()
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
@ -107,23 +152,32 @@
|
|||
slide
|
||||
},
|
||||
methods: {
|
||||
onClickPostButton() {
|
||||
let text = this.get('text')
|
||||
let media = this.get('media')
|
||||
let postPrivacyKey = this.get('postPrivacyKey')
|
||||
let contentWarning = this.get('contentWarning')
|
||||
let sensitive = media.length && !!contentWarning
|
||||
let realm = this.get('realm')
|
||||
let mediaIds = media.map(_ => _.data.id)
|
||||
let inReplyTo = realm === 'home' ? null : realm
|
||||
let overLimit = this.get('overLimit')
|
||||
async onClickPostButton() {
|
||||
if (this.get('sticky')) {
|
||||
// when the button is sticky, we're scrolled down the home timeline,
|
||||
// so we should launch a new compose dialog
|
||||
let dialogs = await importDialogs()
|
||||
dialogs.showComposeDialog()
|
||||
} else {
|
||||
// else we're actually posting a new toot
|
||||
let text = this.get('text')
|
||||
let media = this.get('media')
|
||||
let postPrivacyKey = this.get('postPrivacyKey')
|
||||
let contentWarning = this.get('contentWarning')
|
||||
let sensitive = media.length && !!contentWarning
|
||||
let realm = this.get('realm')
|
||||
let mediaIds = media.map(_ => _.data.id)
|
||||
let inReplyTo = (realm === 'home' || realm === 'dialog') ? null : realm
|
||||
let overLimit = this.get('overLimit')
|
||||
|
||||
if (!text || overLimit) {
|
||||
return // do nothing if invalid
|
||||
if (!text || overLimit) {
|
||||
return // do nothing if invalid
|
||||
}
|
||||
|
||||
/* no await */
|
||||
postStatus(realm, text, inReplyTo, mediaIds,
|
||||
sensitive, contentWarning, postPrivacyKey)
|
||||
}
|
||||
|
||||
/* no await */ postStatus(realm, text, inReplyTo, mediaIds,
|
||||
sensitive, contentWarning, postPrivacyKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,40 @@
|
|||
<button class="primary compose-box-button"
|
||||
:disabled
|
||||
on:click>
|
||||
<span class="{{$postingStatus ? 'hidden' : ''}}">
|
||||
Toot!
|
||||
</span>
|
||||
<div class="compose-box-button-spinner {{$postingStatus ? 'spin' : 'hidden'}}"
|
||||
aria-hidden="true">
|
||||
<svg class="compose-box-button-spinner-svg">
|
||||
<use xlink:href="#fa-spinner" />
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
<div class="compose-box-button-halo frosted-glass">
|
||||
<button class="primary compose-box-button"
|
||||
:disabled
|
||||
aria-label="{{sticky ? 'Compose' : 'Toot!'}}"
|
||||
on:click>
|
||||
<span class="{{$postingStatus || sticky ? 'hidden' : ''}}">
|
||||
Toot!
|
||||
</span>
|
||||
<div class="compose-box-button-spinner {{$postingStatus ? 'spin' : 'hidden'}}"
|
||||
aria-hidden="true">
|
||||
<svg class="compose-box-button-svg">
|
||||
<use xlink:href="#fa-spinner" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="compose-box-button-compose {{sticky ? '' : 'hidden'}}"
|
||||
aria-hidden="true">
|
||||
<svg class="compose-box-button-svg">
|
||||
<use xlink:href="#fa-pencil" />
|
||||
</svg>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<style>
|
||||
.compose-box-button-halo {
|
||||
border-radius: 2px;
|
||||
margin: 5px 15px 15px 5px;
|
||||
background: var(--compose-button-halo);
|
||||
}
|
||||
.compose-box-button {
|
||||
grid-area: button;
|
||||
justify-self: right;
|
||||
text-transform: uppercase;
|
||||
margin-top: 10px;
|
||||
position: relative;
|
||||
margin: 5px;
|
||||
}
|
||||
.compose-box-button-spinner {
|
||||
pointer-events: none;
|
||||
.compose-box-button-spinner, .compose-box-button-compose {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
@ -31,11 +45,20 @@
|
|||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
.compose-box-button-spinner-svg {
|
||||
.compose-box-button-svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
fill: var(--button-primary-text);
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.compose-box-button-halo {
|
||||
margin: 5px;
|
||||
}
|
||||
.compose-box-button {
|
||||
margin: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import { store } from '../../_store/store'
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<ModalDialog :label :shown :closed :title background="var(--main-bg)">
|
||||
<ComposeBox realm="dialog" on:postedStatus="onPostedStatus()" />
|
||||
</ModalDialog>
|
||||
<script>
|
||||
import ModalDialog from './ModalDialog.html'
|
||||
import ComposeBox from '../compose/ComposeBox.html'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ModalDialog,
|
||||
ComposeBox
|
||||
},
|
||||
methods: {
|
||||
async show() {
|
||||
this.set({shown: true})
|
||||
},
|
||||
onPostedStatus() {
|
||||
this.set({closed: true})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -4,7 +4,7 @@
|
|||
></div>
|
||||
<div class="modal-dialog-contents {{fadedIn ? '' : 'hidden'}} {{muted ? 'muted-style' : ''}}"
|
||||
role="dialog"
|
||||
aria-label="{{label}}"
|
||||
aria-label="{{label || ''}}"
|
||||
ref:node
|
||||
>
|
||||
<div class="modal-dialog-document" role="document" style="background: {{background || '#000'}};">
|
||||
|
@ -41,7 +41,10 @@
|
|||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-filter: blur(0);
|
||||
will-change: transform;
|
||||
transform: translate(-50%, -50%);
|
||||
-webkit-font-smoothing: antialiased; /* fix for transform:translate causing blurry text in Chrome/Safari */
|
||||
padding: 0;
|
||||
border: 1px solid var(--main-border);
|
||||
border-radius: 2px;
|
||||
|
|
|
@ -4,3 +4,4 @@ export * from './showVideoDialog'
|
|||
export * from './showEmojiDialog'
|
||||
export * from './showPostPrivacyDialog'
|
||||
export * from './showStatusOptionsDialog'
|
||||
export * from './showComposeDialog'
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import ComposeDialog from './ComposeDialog.html'
|
||||
|
||||
export function showComposeDialog () {
|
||||
let dialog = new ComposeDialog({
|
||||
target: document.getElementById('modal-dialog'),
|
||||
data: {
|
||||
label: 'Compose dialog'
|
||||
}
|
||||
})
|
||||
dialog.show()
|
||||
}
|
|
@ -78,4 +78,6 @@
|
|||
--compose-autosuggest-item-hover: $compose-background;
|
||||
--compose-autosuggest-item-active: darken($compose-background, 5%);
|
||||
--compose-autosuggest-outline: lighten($focus-outline, 5%);
|
||||
|
||||
--compose-button-halo: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
|
||||
<style>
|
||||
/* auto-generated w/ build-sass.js */
|
||||
body{--button-primary-bg:#6081e6;--button-primary-text:#fff;--button-primary-border:#132c76;--button-primary-bg-active:#456ce2;--button-primary-bg-hover:#6988e7;--button-bg:#e6e6e6;--button-text:#333;--button-border:#a7a7a7;--button-bg-active:#bfbfbf;--button-bg-hover:#f2f2f2;--input-border:#dadada;--anchor-text:#4169e1;--main-bg:#fff;--body-bg:#e8edfb;--body-text-color:#333;--main-border:#dadada;--svg-fill:#4169e1;--form-bg:#f7f7f7;--form-border:#c1c1c1;--nav-bg:#4169e1;--nav-border:#214cce;--nav-a-border:#4169e1;--nav-a-selected-border:#fff;--nav-a-selected-bg:#6d8ce8;--nav-svg-fill:#fff;--nav-text-color:#fff;--nav-a-selected-border-hover:#fff;--nav-a-selected-bg-hover:#839deb;--nav-a-bg-hover:#577ae4;--nav-a-border-hover:#4169e1;--nav-svg-fill-hover:#fff;--nav-text-color-hover:#fff;--action-button-fill-color:#90a8ee;--action-button-fill-color-hover:#a2b6f0;--action-button-fill-color-active:#577ae4;--action-button-fill-color-pressed:#2351dc;--action-button-fill-color-pressed-hover:#3862e0;--action-button-fill-color-pressed-active:#1d44b8;--settings-list-item-bg:#fff;--settings-list-item-text:#4169e1;--settings-list-item-text-hover:#4169e1;--settings-list-item-border:#dadada;--settings-list-item-bg-active:#e6e6e6;--settings-list-item-bg-hover:#fafafa;--toast-bg:#333;--toast-border:#fafafa;--toast-text:#fff;--mask-bg:#333;--mask-svg-fill:#fff;--mask-opaque-bg:rgba(51,51,51,0.8);--loading-bg:#ededed;--deemphasized-text-color:#666;--focus-outline:#c5d1f6;--very-deemphasized-link-color:rgba(65,105,225,0.6);--very-deemphasized-text-color:rgba(102,102,102,0.6);--status-direct-background:#d2dcf8;--main-theme-color:#4169e1;--warning-color:#e01f19;--alt-input-bg:rgba(255,255,255,0.7);--muted-modal-bg:transparent;--muted-modal-focus:#999;--muted-modal-hover:rgba(255,255,255,0.2);--compose-autosuggest-item-hover:#ced8f7;--compose-autosuggest-item-active:#b8c7f4;--compose-autosuggest-outline:#dbe3f9}
|
||||
body{--button-primary-bg:#6081e6;--button-primary-text:#fff;--button-primary-border:#132c76;--button-primary-bg-active:#456ce2;--button-primary-bg-hover:#6988e7;--button-bg:#e6e6e6;--button-text:#333;--button-border:#a7a7a7;--button-bg-active:#bfbfbf;--button-bg-hover:#f2f2f2;--input-border:#dadada;--anchor-text:#4169e1;--main-bg:#fff;--body-bg:#e8edfb;--body-text-color:#333;--main-border:#dadada;--svg-fill:#4169e1;--form-bg:#f7f7f7;--form-border:#c1c1c1;--nav-bg:#4169e1;--nav-border:#214cce;--nav-a-border:#4169e1;--nav-a-selected-border:#fff;--nav-a-selected-bg:#6d8ce8;--nav-svg-fill:#fff;--nav-text-color:#fff;--nav-a-selected-border-hover:#fff;--nav-a-selected-bg-hover:#839deb;--nav-a-bg-hover:#577ae4;--nav-a-border-hover:#4169e1;--nav-svg-fill-hover:#fff;--nav-text-color-hover:#fff;--action-button-fill-color:#90a8ee;--action-button-fill-color-hover:#a2b6f0;--action-button-fill-color-active:#577ae4;--action-button-fill-color-pressed:#2351dc;--action-button-fill-color-pressed-hover:#3862e0;--action-button-fill-color-pressed-active:#1d44b8;--settings-list-item-bg:#fff;--settings-list-item-text:#4169e1;--settings-list-item-text-hover:#4169e1;--settings-list-item-border:#dadada;--settings-list-item-bg-active:#e6e6e6;--settings-list-item-bg-hover:#fafafa;--toast-bg:#333;--toast-border:#fafafa;--toast-text:#fff;--mask-bg:#333;--mask-svg-fill:#fff;--mask-opaque-bg:rgba(51,51,51,0.8);--loading-bg:#ededed;--deemphasized-text-color:#666;--focus-outline:#c5d1f6;--very-deemphasized-link-color:rgba(65,105,225,0.6);--very-deemphasized-text-color:rgba(102,102,102,0.6);--status-direct-background:#d2dcf8;--main-theme-color:#4169e1;--warning-color:#e01f19;--alt-input-bg:rgba(255,255,255,0.7);--muted-modal-bg:transparent;--muted-modal-focus:#999;--muted-modal-hover:rgba(255,255,255,0.2);--compose-autosuggest-item-hover:#ced8f7;--compose-autosuggest-item-active:#b8c7f4;--compose-autosuggest-outline:#dbe3f9;--compose-button-halo:rgba(255,255,255,0.2)}
|
||||
body{margin:0;font-family:system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue;font-size:14px;line-height:1.4;color:var(--body-text-color);background:var(--body-bg);position:fixed;left:0;right:0;bottom:0;top:0}.container{overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;will-change:transform;position:absolute;top:72px;left:0;right:0;bottom:0}@media (max-width: 767px){.container{top:62px}}main{position:relative;width:602px;max-width:100vw;padding:0;box-sizing:border-box;margin:30px auto 15px;background:var(--main-bg);border:1px solid var(--main-border);border-radius:1px;min-height:70vh}@media (max-width: 767px){main{margin:5px auto 15px}}footer{width:602px;max-width:100vw;box-sizing:border-box;margin:20px auto;border-radius:1px;background:var(--main-bg);font-size:0.9em;padding:20px;border:1px solid var(--main-border)}h1,h2,h3,h4,h5,h6{margin:0 0 0.5em 0;font-weight:400;line-height:1.2}h1{font-size:2em}a{color:var(--anchor-text);text-decoration:none}a:visited{color:var(--anchor-text)}a:hover{text-decoration:underline}input{border:1px solid var(--input-border);padding:5px;box-sizing:border-box}button,.button{font-size:1.2em;background:var(--button-bg);border-radius:2px;padding:10px 15px;border:1px solid var(--button-border);cursor:pointer;color:var(--button-text)}button:hover,.button:hover{background:var(--button-bg-hover);text-decoration:none}button:active,.button:active{background:var(--button-bg-active)}button[disabled],.button[disabled]{opacity:0.35;pointer-events:none;cursor:not-allowed}button.primary,.button.primary{border:1px solid var(--button-primary-border);background:var(--button-primary-bg);color:var(--button-primary-text)}button.primary:hover,.button.primary:hover{background:var(--button-primary-bg-hover)}button.primary:active,.button.primary:active{background:var(--button-primary-bg-active)}p,label,input{font-size:1.3em}ul,li,p{padding:0;margin:0}.hidden{opacity:0}*:focus{outline:2px solid var(--focus-outline)}button::-moz-focus-inner{border:0}input:required,input:invalid{box-shadow:none}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}.ellipsis::after{content:"\2026"}
|
||||
body.offline,body.theme-hotpants.offline,body.theme-majesty.offline,body.theme-oaken.offline,body.theme-scarlet.offline,body.theme-seafoam.offline,body.theme-gecko.offline{--button-primary-bg:#ababab;--button-primary-text:#fff;--button-primary-border:#4d4d4d;--button-primary-bg-active:#9c9c9c;--button-primary-bg-hover:#b0b0b0;--button-bg:#e6e6e6;--button-text:#333;--button-border:#a7a7a7;--button-bg-active:#bfbfbf;--button-bg-hover:#f2f2f2;--input-border:#dadada;--anchor-text:#999;--main-bg:#fff;--body-bg:#fafafa;--body-text-color:#333;--main-border:#dadada;--svg-fill:#999;--form-bg:#f7f7f7;--form-border:#c1c1c1;--nav-bg:#999;--nav-border:gray;--nav-a-border:#999;--nav-a-selected-border:#fff;--nav-a-selected-bg:#b3b3b3;--nav-svg-fill:#fff;--nav-text-color:#fff;--nav-a-selected-border-hover:#fff;--nav-a-selected-bg-hover:#bfbfbf;--nav-a-bg-hover:#a6a6a6;--nav-a-border-hover:#999;--nav-svg-fill-hover:#fff;--nav-text-color-hover:#fff;--action-button-fill-color:#c7c7c7;--action-button-fill-color-hover:#d1d1d1;--action-button-fill-color-active:#a6a6a6;--action-button-fill-color-pressed:#878787;--action-button-fill-color-pressed-hover:#949494;--action-button-fill-color-pressed-active:#737373;--settings-list-item-bg:#fff;--settings-list-item-text:#999;--settings-list-item-text-hover:#999;--settings-list-item-border:#dadada;--settings-list-item-bg-active:#e6e6e6;--settings-list-item-bg-hover:#fafafa;--toast-bg:#333;--toast-border:#fafafa;--toast-text:#fff;--mask-bg:#333;--mask-svg-fill:#fff;--mask-opaque-bg:rgba(51,51,51,0.8);--loading-bg:#ededed;--deemphasized-text-color:#666;--focus-outline:#bfbfbf;--very-deemphasized-link-color:rgba(153,153,153,0.6);--very-deemphasized-text-color:rgba(102,102,102,0.6);--status-direct-background:#ededed;--main-theme-color:#999;--warning-color:#e01f19;--alt-input-bg:rgba(255,255,255,0.7);--muted-modal-bg:transparent;--muted-modal-focus:#999;--muted-modal-hover:rgba(255,255,255,0.2);--compose-autosuggest-item-hover:#c4c4c4;--compose-autosuggest-item-active:#b8b8b8;--compose-autosuggest-outline:#ccc}
|
||||
body.offline,body.theme-hotpants.offline,body.theme-majesty.offline,body.theme-oaken.offline,body.theme-scarlet.offline,body.theme-seafoam.offline,body.theme-gecko.offline{--button-primary-bg:#ababab;--button-primary-text:#fff;--button-primary-border:#4d4d4d;--button-primary-bg-active:#9c9c9c;--button-primary-bg-hover:#b0b0b0;--button-bg:#e6e6e6;--button-text:#333;--button-border:#a7a7a7;--button-bg-active:#bfbfbf;--button-bg-hover:#f2f2f2;--input-border:#dadada;--anchor-text:#999;--main-bg:#fff;--body-bg:#fafafa;--body-text-color:#333;--main-border:#dadada;--svg-fill:#999;--form-bg:#f7f7f7;--form-border:#c1c1c1;--nav-bg:#999;--nav-border:gray;--nav-a-border:#999;--nav-a-selected-border:#fff;--nav-a-selected-bg:#b3b3b3;--nav-svg-fill:#fff;--nav-text-color:#fff;--nav-a-selected-border-hover:#fff;--nav-a-selected-bg-hover:#bfbfbf;--nav-a-bg-hover:#a6a6a6;--nav-a-border-hover:#999;--nav-svg-fill-hover:#fff;--nav-text-color-hover:#fff;--action-button-fill-color:#c7c7c7;--action-button-fill-color-hover:#d1d1d1;--action-button-fill-color-active:#a6a6a6;--action-button-fill-color-pressed:#878787;--action-button-fill-color-pressed-hover:#949494;--action-button-fill-color-pressed-active:#737373;--settings-list-item-bg:#fff;--settings-list-item-text:#999;--settings-list-item-text-hover:#999;--settings-list-item-border:#dadada;--settings-list-item-bg-active:#e6e6e6;--settings-list-item-bg-hover:#fafafa;--toast-bg:#333;--toast-border:#fafafa;--toast-text:#fff;--mask-bg:#333;--mask-svg-fill:#fff;--mask-opaque-bg:rgba(51,51,51,0.8);--loading-bg:#ededed;--deemphasized-text-color:#666;--focus-outline:#bfbfbf;--very-deemphasized-link-color:rgba(153,153,153,0.6);--very-deemphasized-text-color:rgba(102,102,102,0.6);--status-direct-background:#ededed;--main-theme-color:#999;--warning-color:#e01f19;--alt-input-bg:rgba(255,255,255,0.7);--muted-modal-bg:transparent;--muted-modal-focus:#999;--muted-modal-hover:rgba(255,255,255,0.2);--compose-autosuggest-item-hover:#c4c4c4;--compose-autosuggest-item-active:#b8b8b8;--compose-autosuggest-outline:#ccc;--compose-button-halo:rgba(255,255,255,0.2)}
|
||||
|
||||
</style>
|
||||
|
||||
|
@ -109,6 +109,7 @@ body.offline,body.theme-hotpants.offline,body.theme-majesty.offline,body.theme-o
|
|||
<symbol id="fa-check" viewBox="0 0 1792 1792"><title>Check</title><path d="M1671 566q0 40-28 68l-724 724-136 136q-28 28-68 28t-68-28l-136-136-362-362q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 295 656-657q28-28 68-28t68 28l136 136q28 28 28 68z"></path></symbol>
|
||||
<symbol id="fa-trash" viewBox="0 0 1792 1792"><title>Delete</title><path d="M704 736v576q0 14-9 23t-23 9h-64q-14 0-23-9t-9-23V736q0-14 9-23t23-9h64q14 0 23 9t9 23zm256 0v576q0 14-9 23t-23 9h-64q-14 0-23-9t-9-23V736q0-14 9-23t23-9h64q14 0 23 9t9 23zm256 0v576q0 14-9 23t-23 9h-64q-14 0-23-9t-9-23V736q0-14 9-23t23-9h64q14 0 23 9t9 23zm128 724V512H448v948q0 22 7 40.5t14.5 27 10.5 8.5h832q3 0 10.5-8.5t14.5-27 7-40.5zM672 384h448l-48-117q-7-9-17-11H738q-10 2-17 11zm928 32v64q0 14-9 23t-23 9h-96v948q0 83-47 143.5t-113 60.5H480q-66 0-113-58.5T320 1464V512h-96q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h309l70-167q15-37 54-63t79-26h320q40 0 79 26t54 63l70 167h309q14 0 23 9t9 23z"></path></symbol>
|
||||
<symbol id="fa-hourglass" viewBox="0 0 1792 1792"><title>Follow requested</title><path d="M1632 1600q14 0 23 9t9 23v128q0 14-9 23t-23 9H160q-14 0-23-9t-9-23v-128q0-14 9-23t23-9h1472zm-1374-64q3-55 16-107t30-95 46-87 53.5-76 64.5-69.5 66-60 70.5-55T671 939t65-43q-43-28-65-43t-66.5-47.5-70.5-55-66-60-64.5-69.5-53.5-76-46-87-30-95-16-107h1276q-3 55-16 107t-30 95-46 87-53.5 76-64.5 69.5-66 60-70.5 55T1121 853t-65 43q43 28 65 43t66.5 47.5 70.5 55 66 60 64.5 69.5 53.5 76 46 87 30 95 16 107H258zM1632 0q14 0 23 9t9 23v128q0 14-9 23t-23 9H160q-14 0-23-9t-9-23V32q0-14 9-23t23-9h1472z"></path></symbol>
|
||||
<symbol id="fa-pencil" viewBox="0 0 1792 1792"><title>Compose</title><path d="M491 1536l91-91-235-235-91 91v107h128v128h107zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17zm-54-192l416 416-832 832H128v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91z"></path></symbol>
|
||||
</svg><!-- end insert svg here -->
|
||||
</svg>
|
||||
<!-- The application will be rendered inside this element,
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
import {
|
||||
composeButton, getNthStatus, scrollToStatus, scrollToTopOfTimeline, modalDialog, sleep, showMoreButton,
|
||||
scrollContainerToTop
|
||||
} from '../utils'
|
||||
import { foobarRole } from '../roles'
|
||||
|
||||
fixture`108-compose-dialog.js`
|
||||
.page`http://localhost:4002`
|
||||
|
||||
test('can compose using a dialog', async t => {
|
||||
await t.useRole(foobarRole)
|
||||
await scrollToStatus(t, 15)
|
||||
await t.expect(modalDialog.getAttribute('aria-hidden')).eql('true')
|
||||
.click(composeButton)
|
||||
.expect(modalDialog.hasAttribute('aria-hidden')).notOk()
|
||||
.typeText(modalDialog.find('.compose-box-input'), 'hello from the modal')
|
||||
.click(modalDialog.find('.compose-box-button-compose'))
|
||||
.expect(modalDialog.getAttribute('aria-hidden')).eql('true')
|
||||
await sleep(5000)
|
||||
await scrollToTopOfTimeline(t)
|
||||
await t.hover(getNthStatus(0))
|
||||
await scrollContainerToTop()
|
||||
await t
|
||||
.expect(showMoreButton.innerText).contains('Show 1 more')
|
||||
.click(showMoreButton)
|
||||
await t.expect(getNthStatus(0).innerText).contains('hello from the modal', {timeout: 20000})
|
||||
})
|
|
@ -6,6 +6,7 @@ const SCROLL_INTERVAL = 1
|
|||
|
||||
export const settingsButton = $('nav a[aria-label=Settings]')
|
||||
export const instanceInput = $('#instanceInput')
|
||||
export const modalDialog = $('#modal-dialog')
|
||||
export const modalDialogContents = $('.modal-dialog-contents')
|
||||
export const closeDialogButton = $('.close-dialog-button')
|
||||
export const notificationsNavButton = $('nav a[href="/notifications"]')
|
||||
|
|
Loading…
Reference in New Issue