diff --git a/package.json b/package.json
index e9a246b3..58aeb363 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
"@fortawesome/free-solid-svg-icons": "5.15.4",
"@fortawesome/vue-fontawesome": "3.0.0-5",
"@kazvmoe-infra/pinch-zoom-element": "1.2.0",
- "@vuelidate/core": "2.0.0-alpha.35",
+ "@vuelidate/core": "2.0.0-alpha.41",
"@vuelidate/validators": "2.0.0-alpha.27",
"body-scroll-lock": "2.7.1",
"chromatism": "3.0.0",
@@ -31,6 +31,7 @@
"cropperjs": "1.5.12",
"diff": "3.5.0",
"escape-html": "1.0.3",
+ "js-cookie": "^3.0.1",
"localforage": "1.10.0",
"parse-link-header": "1.0.1",
"phoenix": "1.6.2",
@@ -106,7 +107,7 @@
"sass": "1.20.1",
"sass-loader": "7.2.0",
"selenium-server": "2.53.1",
- "semver": "5.6.0",
+ "semver": "5.7.1",
"serviceworker-webpack-plugin": "1.0.1",
"shelljs": "0.8.5",
"sinon": "2.4.1",
@@ -120,7 +121,7 @@
"webpack": "4.46.0",
"webpack-dev-middleware": "3.7.3",
"webpack-hot-middleware": "2.24.3",
- "webpack-merge": "0.14.1"
+ "webpack-merge": "0.20.0"
},
"engines": {
"node": ">= 4.0.0",
diff --git a/src/App.js b/src/App.js
index d598b011..f01f8788 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,6 +1,5 @@
import UserPanel from './components/user_panel/user_panel.vue'
import NavPanel from './components/nav_panel/nav_panel.vue'
-import Notifications from './components/notifications/notifications.vue'
import InstanceSpecificPanel from './components/instance_specific_panel/instance_specific_panel.vue'
import FeaturesPanel from './components/features_panel/features_panel.vue'
import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue'
@@ -16,13 +15,14 @@ import PostStatusModal from './components/post_status_modal/post_status_modal.vu
import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
import { windowWidth, windowHeight } from './services/window_utils/window_utils'
import { mapGetters } from 'vuex'
+import { defineAsyncComponent } from 'vue'
export default {
name: 'app',
components: {
UserPanel,
NavPanel,
- Notifications,
+ Notifications: defineAsyncComponent(() => import('./components/notifications/notifications.vue')),
InstanceSpecificPanel,
FeaturesPanel,
WhoToFollowPanel,
@@ -50,6 +50,16 @@ export default {
window.removeEventListener('resize', this.updateMobileState)
},
computed: {
+ classes () {
+ return [
+ {
+ '-reverse': this.reverseLayout,
+ '-no-sticky-headers': this.noSticky,
+ '-has-new-post-button': this.newPostButtonShown
+ },
+ '-' + this.layoutType
+ ]
+ },
currentUser () { return this.$store.state.users.currentUser },
userBackground () { return this.currentUser.background_image },
instanceBackground () {
@@ -72,44 +82,38 @@ export default {
!this.$store.getters.mergedConfig.hideISP &&
this.$store.state.instance.instanceSpecificPanelContent
},
- thirdColumnEnabled () {
- return this.$store.getters.mergedConfig.showThirdColumn || false
+ isChats () {
+ return this.$route.name === 'chat' || this.$route.name === 'chats'
+ },
+ newPostButtonShown () {
+ if (this.isChats) return false
+ return this.$store.getters.mergedConfig.alwaysShowNewPostButton || this.layoutType === 'mobile'
},
showFeaturesPanel () { return this.$store.state.instance.showFeaturesPanel },
shoutboxPosition () {
- return this.$store.getters.mergedConfig.showNewPostButton || false
+ return this.$store.getters.mergedConfig.alwaysShowNewPostButton || false
},
hideShoutbox () {
return this.$store.getters.mergedConfig.hideShoutbox
},
- isMobileLayout () { return this.$store.state.interface.mobileLayout },
+ layoutType () { return this.$store.state.interface.layoutType },
privateMode () { return this.$store.state.instance.private },
- sidebarAlign () {
- return {
- 'order': this.$store.getters.mergedConfig.sidebarRight ? 99 : 0
- }
- },
- thirdColumnAlign () {
- return {
- 'order': this.$store.getters.mergedConfig.sidebarRight ? 0 : 99
- }
- },
- thirdColumnLayout () {
- return {
- 'max-width': this.$store.getters.mergedConfig.showThirdColumn ? '1400px' : '980px'
+ reverseLayout () {
+ const { thirdColumnMode, sidebarRight: reverseSetting } = this.$store.getters.mergedConfig
+ if (this.layoutType !== 'wide') {
+ return reverseSetting
+ } else {
+ return thirdColumnMode === 'notifications' ? reverseSetting : !reverseSetting
}
},
+ noSticky () { return this.$store.getters.mergedConfig.disableStickyHeaders },
+ showScrollbars () { return this.$store.getters.mergedConfig.showScrollbars },
...mapGetters(['mergedConfig'])
},
methods: {
updateMobileState () {
- const mobileLayout = windowWidth() <= 800
- const layoutHeight = windowHeight()
- const changed = mobileLayout !== this.isMobileLayout
- if (changed) {
- this.$store.dispatch('setMobileLayout', mobileLayout)
- }
- this.$store.dispatch('setLayoutHeight', layoutHeight)
+ this.$store.dispatch('setLayoutWidth', windowWidth())
+ this.$store.dispatch('setLayoutHeight', windowHeight())
}
}
}
diff --git a/src/App.scss b/src/App.scss
index 306cd6b3..5cd0b96e 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -1,77 +1,333 @@
+// stylelint-disable rscss/class-format
@import './_variables.scss';
-#app {
- min-height: 100vh;
- max-width: 100%;
- overflow: hidden;
-}
-
-.app-bg-wrapper {
- position: fixed;
- z-index: -1;
- height: 100%;
- left: 0;
- right: -20px;
- background-size: cover;
- background-repeat: no-repeat;
- background-color: var(--wallpaper);
- background-image: var(--body-background-image);
- background-position: 50% 50px;
-}
-
-i[class^='icon-'] {
- user-select: none;
-}
-
-h4 {
- margin: 0;
-}
-
-#content {
- box-sizing: border-box;
- padding-top: 60px;
- margin: auto;
- min-height: 100vh;
- max-width: 980px;
- align-content: flex-start;
-}
-
-.underlay {
- background-color: rgba(0,0,0,0.15);
- background-color: var(--underlay, rgba(0,0,0,0.15));
-}
-
-.text-center {
- text-align: center;
+:root {
+ --navbar-height: 3.5rem;
+ --post-line-height: 1.4;
}
html {
font-size: 14px;
+ // overflow-x: clip causes my browser's tab to crash with SIGILL lul
}
body {
- overscroll-behavior-y: none;
font-family: sans-serif;
font-family: var(--interfaceFont, sans-serif);
margin: 0;
color: $fallback--text;
color: var(--text, $fallback--text);
- max-width: 100vw;
- overflow-x: hidden;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
+ overscroll-behavior-y: none;
+ overflow-x: clip;
+ overflow-y: scroll;
&.hidden {
display: none;
}
}
+// ## Custom scrollbars
+// Only show custom scrollbars on devices which
+// have a cursor/pointer to operate them
+@media (any-pointer: fine) {
+ * {
+ scrollbar-color: var(--btn) transparent;
+
+ &::-webkit-scrollbar {
+ background: transparent;
+ }
+
+ &::-webkit-scrollbar-button,
+ &::-webkit-scrollbar-thumb {
+ background-color: var(--btn);
+ box-shadow: var(--buttonShadow);
+ border-radius: var(--btnRadius);
+ }
+
+ // horizontal/vertical/increment/decrement are webkit-specific stuff
+ // that indicates whether we're affecting vertical scrollbar, increase button etc
+ // stylelint-disable selector-pseudo-class-no-unknown
+ &::-webkit-scrollbar-button {
+ --___bgPadding: 2px;
+
+ color: var(--btnText);
+ background-repeat: no-repeat, no-repeat;
+
+ &:horizontal {
+ background-size: 50% calc(50% - var(--___bgPadding)), 50% calc(50% - var(--___bgPadding));
+
+ &:increment {
+ background-image:
+ linear-gradient(45deg, var(--btnText) 50%, transparent 51%),
+ linear-gradient(-45deg, transparent 50%, var(--btnText) 51%);
+ background-position: top var(--___bgPadding) left 50%, right 50% bottom var(--___bgPadding);
+ }
+
+ &:decrement {
+ background-image:
+ linear-gradient(45deg, transparent 50%, var(--btnText) 51%),
+ linear-gradient(-45deg, var(--btnText) 50%, transparent 51%);
+ background-position: bottom var(--___bgPadding) right 50%, left 50% top var(--___bgPadding);
+ }
+ }
+
+ &:vertical {
+ background-size: calc(50% - var(--___bgPadding)) 50%, calc(50% - var(--___bgPadding)) 50%;
+
+ &:increment {
+ background-image:
+ linear-gradient(-45deg, transparent 50%, var(--btnText) 51%),
+ linear-gradient(45deg, transparent 50%, var(--btnText) 51%);
+ background-position: right var(--___bgPadding) top 50%, left var(--___bgPadding) top 50%;
+ }
+
+ &:decrement {
+ background-image:
+ linear-gradient(-45deg, var(--btnText) 50%, transparent 51%),
+ linear-gradient(45deg, var(--btnText) 50%, transparent 51%);
+ background-position: left var(--___bgPadding) top 50%, right var(--___bgPadding) top 50%;
+ }
+ }
+ }
+ // stylelint-enable selector-pseudo-class-no-unknown
+ }
+ // Body should have background to scrollbar otherwise it will use white (body color?)
+ html {
+ scrollbar-color: var(--selectedMenu) var(--wallpaper);
+ background: var(--wallpaper);
+ }
+}
+
a {
text-decoration: none;
color: $fallback--link;
color: var(--link, $fallback--link);
}
+h4 {
+ margin: 0;
+}
+
+i[class*=icon-],
+.svg-inline--fa {
+ color: $fallback--icon;
+ color: var(--icon, $fallback--icon);
+}
+
+nav {
+ z-index: 1000;
+ color: var(--topBarText);
+ background-color: $fallback--fg;
+ background-color: var(--topBar, $fallback--fg);
+ color: $fallback--faint;
+ color: var(--faint, $fallback--faint);
+ box-shadow: 0 0 4px rgba(0, 0, 0, 0.6);
+ box-shadow: var(--topBarShadow);
+ box-sizing: border-box;
+ height: var(--navbar-height);
+ position: fixed;
+}
+
+#sidebar {
+ grid-area: sidebar;
+}
+
+.column.-scrollable {
+ top: var(--navbar-height);
+ position: sticky;
+}
+
+#main-scroller {
+ grid-area: content;
+ position: relative;
+}
+
+#notifs-column {
+ grid-area: notifs;
+}
+
+.app-bg-wrapper {
+ position: fixed;
+ height: 100%;
+ top: var(--navbar-height);
+ z-index: -1000;
+ left: 0;
+ right: -20px;
+ background-size: cover;
+ background-repeat: no-repeat;
+ background-color: var(--wallpaper);
+ background-image: var(--body-background-image);
+ background-position: 50%;
+}
+
+.underlay {
+ grid-column-start: 1;
+ grid-column-end: span 3;
+ grid-row-start: 1;
+ grid-row-end: 1;
+ pointer-events: none;
+ background-color: rgba(0, 0, 0, 0.15);
+ background-color: var(--underlay, rgba(0, 0, 0, 0.15));
+ z-index: -1000;
+}
+
+.app-layout {
+ --miniColumn: 25rem;
+ --maxiColumn: minmax(var(--miniColumn), 45rem);
+ --columnGap: 1em;
+ --status-margin: 0.75em;
+
+ position: relative;
+ display: grid;
+ grid-template-columns: var(--miniColumn) var(--maxiColumn);
+ grid-template-areas: "sidebar content";
+ grid-template-rows: 1fr;
+ box-sizing: border-box;
+ margin: 0 auto;
+ align-content: flex-start;
+ flex-wrap: wrap;
+ justify-content: center;
+ min-height: 100vh;
+ overflow-x: clip;
+
+ .column {
+ --___columnMargin: var(--columnGap);
+
+ display: grid;
+ grid-template-columns: 100%;
+ box-sizing: border-box;
+ grid-row-start: 1;
+ grid-row-end: 1;
+ margin: 0 calc(var(--___columnMargin) / 2);
+ padding: calc(var(--___columnMargin)) 0;
+ row-gap: var(--___columnMargin);
+ align-content: start;
+
+ &:not(.-scrollable) {
+ margin-top: var(--navbar-height);
+ }
+
+ &:hover {
+ z-index: 2;
+ }
+
+ &.-full-height {
+ margin-bottom: 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ }
+
+ &.-scrollable {
+ --___paddingIncrease: calc(var(--columnGap) / 2);
+
+ position: sticky;
+ top: var(--navbar-height);
+ max-height: calc(100vh - var(--navbar-height));
+ overflow-y: auto;
+ overflow-x: hidden;
+ margin-left: calc(var(--___paddingIncrease) * -1);
+ padding-left: calc(var(--___paddingIncrease) + var(--___columnMargin) / 2);
+
+ // On browsers that don't support hiding scrollbars we enforce "show scrolbars" mode
+ // might implement old style of hiding scrollbars later if there's demand
+ @supports (scrollbar-width: none) or (-webkit-text-fill-color: initial) {
+ &:not(.-show-scrollbar) {
+ scrollbar-width: none;
+ margin-right: calc(var(--___paddingIncrease) * -1);
+ padding-right: calc(var(--___paddingIncrease) + var(--___columnMargin) / 2);
+
+ &::-webkit-scrollbar {
+ display: block;
+ width: 0;
+ }
+ }
+ }
+
+ .panel-heading.-sticky {
+ top: calc(var(--columnGap) / -1);
+ }
+ }
+ }
+
+ &.-has-new-post-button {
+ .column {
+ padding-bottom: 10rem;
+ }
+ }
+
+ &.-no-sticky-headers {
+ .column {
+ .panel-heading.-sticky {
+ position: relative;
+ top: 0;
+ }
+ }
+ }
+
+ .column-inner {
+ display: grid;
+ grid-template-columns: 100%;
+ box-sizing: border-box;
+ row-gap: 1em;
+ align-content: start;
+ }
+
+ &.-reverse:not(.-wide):not(.-mobile) {
+ grid-template-columns: var(--maxiColumn) var(--miniColumn);
+ grid-template-areas: "content sidebar";
+ }
+
+ &.-wide {
+ grid-template-columns: var(--miniColumn) var(--maxiColumn) var(--miniColumn);
+ grid-template-areas: "sidebar content notifs";
+
+ &.-reverse {
+ grid-template-areas: "notifs content sidebar";
+ }
+ }
+
+ &.-mobile {
+ grid-template-columns: 100vw;
+ grid-template-areas: "content";
+ padding: 0;
+
+ .column {
+ margin-left: 0;
+ margin-right: 0;
+ padding-top: 0;
+ margin-top: var(--navbar-height);
+ margin-bottom: 0;
+ }
+
+ .panel-heading,
+ .panel-heading::after,
+ .panel-heading::before,
+ .panel,
+ .panel::after {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ }
+
+ .underlay,
+ #sidebar,
+ #notifs-column {
+ display: none;
+ }
+ }
+
+ &.-normal {
+ #notifs-column {
+ display: none;
+ }
+ }
+}
+
+.text-center {
+ text-align: center;
+}
+
.button-default {
user-select: none;
color: $fallback--text;
@@ -84,7 +340,7 @@ a {
cursor: pointer;
box-shadow: $fallback--buttonShadow;
box-shadow: var(--buttonShadow);
- font-size: 14px;
+ font-size: 1em;
font-family: sans-serif;
font-family: var(--interfaceFont, sans-serif);
@@ -103,12 +359,12 @@ a {
}
&:hover {
- box-shadow: 0px 0px 4px rgba(255, 255, 255, 0.3);
+ box-shadow: 0 0 4px rgba(255, 255, 255, 0.3);
box-shadow: var(--buttonHoverShadow);
}
&:active {
- box-shadow: 0px 0px 4px 0px rgba(255, 255, 255, 0.3), 0px 1px 0px 0px rgba(0, 0, 0, 0.2) inset, 0px -1px 0px 0px rgba(255, 255, 255, 0.2) inset;
+ box-shadow: 0 0 4px 0 rgba(255, 255, 255, 0.3), 0 1px 0 0 rgba(0, 0, 0, 0.2) inset, 0 -1px 0 0 rgba(255, 255, 255, 0.2) inset;
box-shadow: var(--buttonPressedShadow);
color: $fallback--text;
color: var(--btnPressedText, $fallback--text);
@@ -141,7 +397,7 @@ a {
color: var(--btnToggledText, $fallback--text);
background-color: $fallback--fg;
background-color: var(--btnToggled, $fallback--fg);
- box-shadow: 0px 0px 4px 0px rgba(255, 255, 255, 0.3), 0px 1px 0px 0px rgba(0, 0, 0, 0.2) inset, 0px -1px 0px 0px rgba(255, 255, 255, 0.2) inset;
+ box-shadow: 0 0 4px 0 rgba(255, 255, 255, 0.3), 0 1px 0 0 rgba(0, 0, 0, 0.2) inset, 0 -1px 0 0 rgba(255, 255, 255, 0.2) inset;
box-shadow: var(--buttonPressedShadow);
svg,
@@ -191,8 +447,9 @@ a {
}
}
-input, textarea, .input {
-
+input,
+textarea,
+.input {
&.unstyled {
border-radius: 0;
background: none;
@@ -200,10 +457,12 @@ input, textarea, .input {
height: unset;
}
+ --_padding: 0.5em;
+
border: none;
border-radius: $fallback--inputRadius;
border-radius: var(--inputRadius, $fallback--inputRadius);
- box-shadow: 0px 1px 0px 0px rgba(0, 0, 0, 0.2) inset, 0px -1px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 0px 2px 0px rgba(0, 0, 0, 1) inset;
+ box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.2) inset, 0 -1px 0 0 rgba(255, 255, 255, 0.2) inset, 0 0 2px 0 rgba(0, 0, 0, 1) inset;
box-shadow: var(--inputShadow);
background-color: $fallback--fg;
background-color: var(--input, $fallback--fg);
@@ -211,17 +470,18 @@ input, textarea, .input {
color: var(--inputText, $fallback--lightText);
font-family: sans-serif;
font-family: var(--inputFont, sans-serif);
- font-size: 14px;
+ font-size: 1em;
margin: 0;
box-sizing: border-box;
display: inline-block;
position: relative;
- height: 28px;
- line-height: 16px;
+ line-height: 2;
hyphens: none;
- padding: 8px .5em;
+ padding: 0 var(--_padding);
- &:disabled, &[disabled=disabled], &.disabled {
+ &:disabled,
+ &[disabled=disabled],
+ &.disabled {
cursor: not-allowed;
opacity: 0.5;
}
@@ -236,18 +496,21 @@ input, textarea, .input {
&[type=radio] {
display: none;
+
&:checked + label::before {
- box-shadow: 0px 0px 2px black inset, 0px 0px 0px 4px $fallback--fg inset;
- box-shadow: var(--inputShadow), 0px 0px 0px 4px var(--fg, $fallback--fg) inset;
+ box-shadow: 0 0 2px black inset, 0 0 0 4px $fallback--fg inset;
+ box-shadow: var(--inputShadow), 0 0 0 4px var(--fg, $fallback--fg) inset;
background-color: var(--accent, $fallback--link);
}
+
&:disabled {
&,
& + label,
& + label::before {
- opacity: .5;
+ opacity: 0.5;
}
}
+
+ label::before {
flex-shrink: 0;
display: inline-block;
@@ -256,35 +519,37 @@ input, textarea, .input {
width: 1.1em;
height: 1.1em;
border-radius: 100%; // Radio buttons should always be circle
- box-shadow: 0px 0px 2px black inset;
+ box-shadow: 0 0 2px black inset;
box-shadow: var(--inputShadow);
- margin-right: .5em;
+ margin-right: 0.5em;
background-color: $fallback--fg;
background-color: var(--input, $fallback--fg);
vertical-align: top;
text-align: center;
- line-height: 1.1em;
+ line-height: 1.1;
font-size: 1.1em;
box-sizing: border-box;
color: transparent;
overflow: hidden;
- box-sizing: border-box;
}
}
&[type=checkbox] {
display: none;
+
&:checked + label::before {
color: $fallback--text;
color: var(--inputText, $fallback--text);
}
+
&:disabled {
&,
& + label,
& + label::before {
- opacity: .5;
+ opacity: 0.5;
}
}
+
+ label::before {
flex-shrink: 0;
display: inline-block;
@@ -294,19 +559,18 @@ input, textarea, .input {
height: 1.1em;
border-radius: $fallback--checkboxRadius;
border-radius: var(--checkboxRadius, $fallback--checkboxRadius);
- box-shadow: 0px 0px 2px black inset;
+ box-shadow: 0 0 2px black inset;
box-shadow: var(--inputShadow);
- margin-right: .5em;
+ margin-right: 0.5em;
background-color: $fallback--fg;
background-color: var(--input, $fallback--fg);
vertical-align: top;
text-align: center;
- line-height: 1.1em;
+ line-height: 1.1;
font-size: 1.1em;
box-sizing: border-box;
color: transparent;
overflow: hidden;
- box-sizing: border-box;
}
}
@@ -315,6 +579,12 @@ input, textarea, .input {
}
}
+// Textareas should have stock line-height + vertical padding instead of huge line-height
+textarea {
+ padding: var(--_padding);
+ line-height: var(--post-line-height);
+}
+
option {
color: $fallback--text;
color: var(--text, $fallback--text);
@@ -324,6 +594,7 @@ option {
.hide-number-spinner {
-moz-appearance: textfield;
+
&[type=number]::-webkit-inner-spin-button,
&[type=number]::-webkit-outer-spin-button {
opacity: 0;
@@ -331,11 +602,6 @@ option {
}
}
-i[class*=icon-], .svg-inline--fa {
- color: $fallback--icon;
- color: var(--icon, $fallback--icon);
-}
-
.btn-block {
display: block;
width: 100%;
@@ -362,274 +628,16 @@ i[class*=icon-], .svg-inline--fa {
}
}
-.container {
- display: flex;
- flex-wrap: wrap;
- margin: 0;
- padding: 0 10px 0 10px;
-}
-
-.auto-size {
- flex: 1
-}
-
-main-router {
- flex: 1;
-}
-
-.status.compact {
- color: rgba(0, 0, 0, 0.42);
- font-weight: 300;
-
- p {
- margin: 0;
- font-size: 0.8em
- }
-}
-
-/* Panel */
-
-.panel {
- display: flex;
- position: relative;
-
- flex-direction: column;
- margin: 0.5em;
-
- background-color: $fallback--bg;
- background-color: var(--bg, $fallback--bg);
-
- &::after, & {
- border-radius: $fallback--panelRadius;
- border-radius: var(--panelRadius, $fallback--panelRadius);
- }
-
- &::after {
- content: '';
- position: absolute;
-
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
-
- pointer-events: none;
-
- box-shadow: 1px 1px 4px rgba(0,0,0,.6);
- box-shadow: var(--panelShadow);
- }
-}
-
-.panel-body:empty::before {
- content: "¯\\_(ツ)_/¯"; // Could use words but it'd require translations
- display: block;
- margin: 1em;
- text-align: center;
-}
-
-.panel-heading {
- display: flex;
- flex: none;
- border-radius: $fallback--panelRadius $fallback--panelRadius 0 0;
- border-radius: var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius) 0 0;
- background-size: cover;
- padding: .6em .6em;
- text-align: left;
- line-height: 28px;
- color: var(--panelText);
- background-color: $fallback--fg;
- background-color: var(--panel, $fallback--fg);
- align-items: baseline;
- box-shadow: var(--panelHeaderShadow);
-
- .title {
- flex: 1 0 auto;
- font-size: 1.3em;
- }
-
- .faint {
- background-color: transparent;
- color: $fallback--faint;
- color: var(--panelFaint, $fallback--faint);
- }
-
- .faint-link {
- color: $fallback--faint;
- color: var(--faintLink, $fallback--faint);
- }
-
- .alert {
- white-space: nowrap;
- text-overflow: ellipsis;
- overflow-x: hidden;
- }
-
- .button-default,
- .alert {
- // height: 100%;
- line-height: 21px;
- min-height: 0;
- box-sizing: border-box;
- margin: 0;
- margin-left: .5em;
- min-width: 1px;
- align-self: stretch;
- }
-
- .button-default {
- flex-shrink: 0;
-
- &,
- i[class*=icon-] {
- color: $fallback--text;
- color: var(--btnPanelText, $fallback--text);
- }
-
- &:active {
- background-color: $fallback--fg;
- background-color: var(--btnPressedPanel, $fallback--fg);
- color: $fallback--text;
- color: var(--btnPressedPanelText, $fallback--text);
- }
-
- &:disabled {
- color: $fallback--text;
- color: var(--btnDisabledPanelText, $fallback--text);
- }
-
- &.toggled {
- color: $fallback--text;
- color: var(--btnToggledPanelText, $fallback--text);
- }
- }
-
- a,
- .-link {
- color: $fallback--link;
- color: var(--panelLink, $fallback--link)
- }
-}
-
-.panel-heading.stub {
- border-radius: $fallback--panelRadius;
- border-radius: var(--panelRadius, $fallback--panelRadius);
-}
-
-/* TODO Should remove timeline-footer from here when we refactor panels into
- * separate component and utilize slots
- */
-.panel-footer, .timeline-footer {
- display: flex;
- border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;
- border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
- flex: none;
- padding: 0.6em 0.6em;
- text-align: left;
- line-height: 28px;
- align-items: baseline;
- border-width: 1px 0 0 0;
- border-style: solid;
- border-color: var(--border, $fallback--border);
-
- .faint {
- color: $fallback--faint;
- color: var(--panelFaint, $fallback--faint);
- }
-
- a,
- .-link {
- color: $fallback--link;
- color: var(--panelLink, $fallback--link);
- }
-}
-
-.panel-body > p {
- line-height: 18px;
- padding: 1em;
- margin: 0;
-}
-
-.container > * {
- min-width: 0px;
-}
+@import './panel.scss';
.fa {
color: grey;
}
-nav {
- z-index: 1000;
- color: var(--topBarText);
- background-color: $fallback--fg;
- background-color: var(--topBar, $fallback--fg);
- color: $fallback--faint;
- color: var(--faint, $fallback--faint);
- box-shadow: 0px 0px 4px rgba(0,0,0,.6);
- box-shadow: var(--topBarShadow);
- box-sizing: border-box;
-}
-
-.fade-enter-active, .fade-leave-active {
- transition: opacity .2s
-}
-.fade-enter-from, .fade-leave-active {
- opacity: 0
-}
-
-.main {
- flex-basis: 25%;
- flex-grow: 1;
- flex-shrink: 1;
- order: 50;
-}
-
-.sidebar-bounds {
- flex: 0;
- flex-basis: 35%;
-}
-
-.sidebar-flexer {
- flex: 1;
- flex-basis: 345px;
- width: 365px;
-}
-
.mobile-shown {
display: none;
}
-@media all and (min-width: 800px) {
- body {
- overflow-y: scroll;
- }
-
- .sidebar-bounds {
- overflow: hidden;
- max-height: 100vh;
- width: 345px;
- position: fixed;
- margin-top: -10px;
-
- .sidebar-scroller {
- height: 96vh;
- width: 365px;
- padding-top: 10px;
- padding-right: 50px;
- overflow-x: hidden;
- overflow-y: scroll;
- }
-
- .sidebar {
- width: 345px;
- }
- }
- .sidebar-flexer {
- max-height: 96vh;
- flex-shrink: 0;
- flex-grow: 0;
- }
-}
-
.badge {
box-sizing: border-box;
display: inline-block;
@@ -657,12 +665,10 @@ nav {
}
.alert {
- margin: 0.35em;
- padding: 0.25em;
+ margin: 0 0.35em;
+ padding: 0 0.25em;
border-radius: $fallback--tooltipRadius;
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
- min-height: 28px;
- line-height: 28px;
&.error {
background-color: $fallback--alertError;
@@ -713,7 +719,7 @@ nav {
}
.visibility-notice {
- padding: .5em;
+ padding: 0.5em;
border: 1px solid $fallback--faint;
border: 1px solid var(--faint, $fallback--faint);
border-radius: $fallback--inputRadius;
@@ -728,7 +734,7 @@ nav {
position: absolute;
top: 0;
right: 0;
- padding: .5em;
+ padding: 0.5em;
color: inherit;
}
}
@@ -745,72 +751,6 @@ nav {
}
}
-@keyframes shakeError {
- 0% {
- transform: translateX(0);
- }
- 15% {
- transform: translateX(0.375rem);
- }
- 30% {
- transform: translateX(-0.375rem);
- }
- 45% {
- transform: translateX(0.375rem);
- }
- 60% {
- transform: translateX(-0.375rem);
- }
- 75% {
- transform: translateX(0.375rem);
- }
- 90% {
- transform: translateX(-0.375rem);
- }
- 100% {
- transform: translateX(0);
- }
-}
-
-@media all and (max-width: 800px) {
- .mobile-hidden {
- display: none;
- }
-
- .panel-switcher {
- display: flex;
- }
-
- .container {
- padding: 0;
- }
-
- .panel {
- margin: 0.5em 0 0.5em 0;
- }
-
- .menu-button {
- display: block;
- margin-right: 0.8em;
- }
-
- .main {
- margin-bottom: 7em;
- }
-}
-
-.setting-list,
-.option-list{
- list-style-type: none;
- padding-left: 2em;
- li {
- margin-bottom: 0.5em;
- }
- .suboptions {
- margin-top: 0.3em
- }
-}
-
.login-hint {
text-align: center;
@@ -820,18 +760,26 @@ nav {
a {
display: inline-block;
- padding: 1em 0px;
+ padding: 1em 0;
width: 100%;
}
}
.btn.button-default {
- min-height: 28px;
+ min-height: 2em;
}
-.animate-spin {
- animation: spin 2s infinite linear;
- display: inline-block;
+.new-status-notification {
+ position: relative;
+ font-size: 1.1em;
+ z-index: 1;
+ flex: 1;
+}
+
+@media all and (max-width: 800px) {
+ .mobile-hidden {
+ display: none;
+ }
}
@keyframes spin {
@@ -844,49 +792,47 @@ nav {
}
}
-.new-status-notification {
- position: relative;
- font-size: 1.1em;
- z-index: 1;
- flex: 1;
-}
-
-.chat-layout {
- // Needed for smoother chat navigation in the desktop Safari (otherwise the chat layout "jumps" as the chat opens).
- overflow: hidden;
- height: 100%;
-
- // Get rid of scrollbar on body as scrolling happens on different element
- body {
- overflow: hidden;
+@keyframes shakeError {
+ 0% {
+ transform: translateX(0);
}
- // Ensures the fixed position of the mobile browser bars on scroll up / down events.
- // Prevents the mobile browser bars from overlapping or hiding the message posting form.
- @media all and (max-width: 800px) {
- body {
- height: 100%;
- }
+ 15% {
+ transform: translateX(0.375rem);
+ }
- #app {
- height: 100%;
- overflow: hidden;
- min-height: auto;
- }
+ 30% {
+ transform: translateX(-0.375rem);
+ }
- #app_bg_wrapper {
- overflow: hidden;
- }
+ 45% {
+ transform: translateX(0.375rem);
+ }
- .main {
- overflow: hidden;
- height: 100%;
- }
+ 60% {
+ transform: translateX(-0.375rem);
+ }
- #content {
- padding-top: 0;
- height: 100%;
- overflow: visible;
- }
+ 75% {
+ transform: translateX(0.375rem);
+ }
+
+ 90% {
+ transform: translateX(-0.375rem);
+ }
+
+ 100% {
+ transform: translateX(0);
}
}
+
+// Vue transitions
+.fade-enter-active,
+.fade-leave-active {
+ transition: opacity 0.2s;
+}
+
+.fade-enter-from,
+.fade-leave-active {
+ opacity: 0;
+}
diff --git a/src/App.vue b/src/App.vue
index 6e09a266..21f6f686 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -7,34 +7,26 @@
id="app_bg_wrapper"
class="app-bg-wrapper"
/>
-
+
-
+
-