forked from AkkomaGang/akkoma-fe
merge
This commit is contained in:
commit
033170212f
63 changed files with 2794 additions and 1621 deletions
|
@ -4,6 +4,7 @@ Contributors of this project.
|
|||
- Coco Snuss (cocosnuss@social.heldscal.la): Code
|
||||
- wakarimasen (wakarimasen@shitposter.club): NSFW hiding image
|
||||
- dtluna (dtluna@social.heldscal.la): Code
|
||||
- sonyam (sonyam@social.heldscal.la): Default background image
|
||||
- sonyam (sonyam@social.heldscal.la): Background images
|
||||
- hakui (hakui@freezepeach.xyz): CSS and styling
|
||||
- shpuld (shpuld@shitposter.club): CSS and styling
|
||||
- Vincent Guth (https://unsplash.com/photos/XrwVIFy6rTw): Background images.
|
||||
|
|
388
src/App.scss
388
src/App.scss
|
@ -1,10 +1,13 @@
|
|||
@import './_variables.scss';
|
||||
|
||||
#app {
|
||||
background-size: cover;
|
||||
background-attachment: fixed;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 50px;
|
||||
min-height: 100vh;
|
||||
background-size: cover;
|
||||
background-attachment: fixed;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 50px;
|
||||
min-height: 100vh;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
i {
|
||||
|
@ -12,7 +15,7 @@ i {
|
|||
}
|
||||
|
||||
h4 {
|
||||
margin: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#content {
|
||||
|
@ -26,154 +29,286 @@ h4 {
|
|||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
color: $fallback--fg;
|
||||
color: var(--fg, $fallback--fg);
|
||||
max-width: 100vw;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
text-decoration: none;
|
||||
color: $fallback--link;
|
||||
color: var(--link, $fallback--link);
|
||||
}
|
||||
|
||||
button{
|
||||
user-select: none;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0px 0px 2px black;
|
||||
font-size: 14px;
|
||||
font-family: sans-serif;
|
||||
user-select: none;
|
||||
color: $fallback--fg;
|
||||
color: var(--fg, $fallback--fg);
|
||||
background-color: $fallback--btn;
|
||||
background-color: var(--btn, $fallback--btn);
|
||||
border: none;
|
||||
border-radius: $fallback--btnRadius;
|
||||
border-radius: var(--btnRadius, $fallback--btnRadius);
|
||||
cursor: pointer;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0px 0px 2px black;
|
||||
font-size: 14px;
|
||||
font-family: sans-serif;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0px 0px 4px rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
&:hover {
|
||||
box-shadow: 0px 0px 4px rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&.pressed {
|
||||
color: $fallback--faint;
|
||||
color: var(--faint, $fallback--faint);
|
||||
background-color: $fallback--bg;
|
||||
background-color: var(--bg, $fallback--bg)
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
label.select {
|
||||
padding: 0;
|
||||
|
||||
}
|
||||
|
||||
input, textarea, .select {
|
||||
border: none;
|
||||
border-radius: $fallback--btnRadius;
|
||||
border-radius: var(--btnRadius, $fallback--btnRadius);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0px 0px 2px black inset;
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--lightBg, $fallback--lightBg);
|
||||
color: $fallback--lightFg;
|
||||
color: var(--lightFg, $fallback--lightFg);
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
padding: 8px 7px;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
height: 29px;
|
||||
line-height: 16px;
|
||||
|
||||
.icon-down-open {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 5px;
|
||||
height: 100%;
|
||||
color: $fallback--fg;
|
||||
color: var(--fg, $fallback--fg);
|
||||
line-height: 29px;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
select {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
background: transparent;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0 10px 0 10px;
|
||||
color: $fallback--fg;
|
||||
color: var(--fg, $fallback--fg);
|
||||
padding: 4px 2em 3px 3px;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
height: 29px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
&[type=radio],
|
||||
&[type=checkbox] {
|
||||
display: none;
|
||||
&:checked + label::before {
|
||||
color: $fallback--fg;
|
||||
color: var(--fg, $fallback--fg);
|
||||
}
|
||||
+ label::before {
|
||||
display: inline-block;
|
||||
content: '✔';
|
||||
transition: color 200ms;
|
||||
width: 1.1em;
|
||||
height: 1.1em;
|
||||
border-radius: $fallback--checkBoxRadius;
|
||||
border-radius: var(--checkBoxRadius, $fallback--checkBoxRadius);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0px 0px 2px black inset;
|
||||
margin-right: .5em;
|
||||
background-color: $fallback--btn;
|
||||
background-color: var(--btn, $fallback--btn);
|
||||
vertical-align: top;
|
||||
text-align: center;
|
||||
line-height: 1.1em;
|
||||
font-size: 1.1em;
|
||||
box-sizing: border-box;
|
||||
color: transparent;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i[class*=icon-] {
|
||||
color: $fallback--icon;
|
||||
color: var(--icon, $fallback--icon)
|
||||
}
|
||||
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 0;
|
||||
padding: 0 10px 0 10px;
|
||||
}
|
||||
|
||||
.gaps {
|
||||
margin: -1em 0 0 -1em;
|
||||
margin: -1em 0 0 -1em;
|
||||
}
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
line-height: 21px;
|
||||
height: 21px;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
line-height: 50px;
|
||||
height: 50px;
|
||||
overflow: hidden;
|
||||
|
||||
.nav-icon {
|
||||
font-size: 1.1em;
|
||||
margin-left: 0.4em;
|
||||
}
|
||||
.nav-icon {
|
||||
font-size: 1.1em;
|
||||
margin-left: 0.4em;
|
||||
}
|
||||
}
|
||||
|
||||
.gaps > .item {
|
||||
padding: 1em 0 0 1em;
|
||||
padding: 1em 0 0 1em;
|
||||
}
|
||||
|
||||
.auto-size {
|
||||
flex: 1
|
||||
flex: 1
|
||||
}
|
||||
|
||||
nav {
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
height: 50px;
|
||||
|
||||
.inner-nav {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-basis: 970px;
|
||||
margin: auto;
|
||||
height: 50px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
.inner-nav {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-basis: 970px;
|
||||
margin: auto;
|
||||
height: 50px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: auto 80%;
|
||||
|
||||
a i {
|
||||
color: $fallback--link;
|
||||
color: var(--link, $fallback--link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main-router {
|
||||
flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.status.compact {
|
||||
color: rgba(0, 0, 0, 0.42);
|
||||
font-weight: 300;
|
||||
color: rgba(0, 0, 0, 0.42);
|
||||
font-weight: 300;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 0.8em
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 0.8em
|
||||
}
|
||||
}
|
||||
|
||||
/* Panel */
|
||||
|
||||
.panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0.5em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0.5em;
|
||||
|
||||
border-radius: 10px;
|
||||
box-shadow: 1px 1px 4px rgba(0,0,0,.6);
|
||||
overflow: hidden;
|
||||
background-color: $fallback--bg;
|
||||
background-color: var(--bg, $fallback--bg);
|
||||
|
||||
border-radius: $fallback--panelRadius;
|
||||
border-radius: var(--panelRadius, $fallback--panelRadius);
|
||||
box-shadow: 1px 1px 4px rgba(0,0,0,.6);
|
||||
}
|
||||
|
||||
.panel-body:empty::before {
|
||||
content: "¯\\_(ツ)_/¯"; // Could use words but it'd require translations
|
||||
display: block;
|
||||
margin: 1em;
|
||||
text-align: center;
|
||||
content: "¯\\_(ツ)_/¯"; // Could use words but it'd require translations
|
||||
display: block;
|
||||
margin: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.panel-heading {
|
||||
border-radius: 10px 10px 0 0;
|
||||
background-size: cover;
|
||||
padding: 0.6em 1.0em;
|
||||
text-align: left;
|
||||
font-size: 1.3em;
|
||||
line-height: 24px;
|
||||
border-radius: $fallback--panelRadius $fallback--panelRadius 0 0;
|
||||
border-radius: var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius) 0 0;
|
||||
background-size: cover;
|
||||
padding: 0.6em 1.0em;
|
||||
text-align: left;
|
||||
font-size: 1.3em;
|
||||
line-height: 24px;
|
||||
background-color: $fallback--btn;
|
||||
background-color: var(--btn, $fallback--btn);
|
||||
}
|
||||
|
||||
.panel-heading.stub {
|
||||
border-radius: $fallback--panelRadius;
|
||||
border-radius: var(--panelRadius, $fallback--panelRadius);
|
||||
}
|
||||
|
||||
.panel-footer {
|
||||
border-radius: 0 0 10px 10px;
|
||||
border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;
|
||||
border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
|
||||
}
|
||||
|
||||
.panel-body > p {
|
||||
line-height: 18px;
|
||||
padding: 1em;
|
||||
margin: 0;
|
||||
line-height: 18px;
|
||||
padding: 1em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.container > * {
|
||||
min-width: 0px;
|
||||
min-width: 0px;
|
||||
}
|
||||
|
||||
.fa {
|
||||
color: grey;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
nav {
|
||||
z-index: 1000;
|
||||
box-shadow: 0px 0px 4px rgba(0,0,0,.6);
|
||||
z-index: 1000;
|
||||
background-color: $fallback--btn;
|
||||
background-color: var(--btn, $fallback--btn);
|
||||
color: $fallback--faint;
|
||||
color: var(--faint, $fallback--faint);
|
||||
box-shadow: 0px 0px 4px rgba(0,0,0,.6);
|
||||
}
|
||||
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
|
@ -184,9 +319,9 @@ nav {
|
|||
}
|
||||
|
||||
.main {
|
||||
flex-basis: 60%;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
flex-basis: 60%;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
.sidebar-bounds {
|
||||
|
@ -201,20 +336,20 @@ nav {
|
|||
}
|
||||
|
||||
.mobile-shown {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.panel-switcher {
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 46px;
|
||||
button {
|
||||
display: block;
|
||||
flex: 1;
|
||||
max-height: 32px;
|
||||
margin: 0.5em;
|
||||
padding: 0.5em;
|
||||
}
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 46px;
|
||||
button {
|
||||
display: block;
|
||||
flex: 1;
|
||||
max-height: 32px;
|
||||
margin: 0.5em;
|
||||
padding: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 960px) {
|
||||
|
@ -248,25 +383,46 @@ nav {
|
|||
}
|
||||
}
|
||||
|
||||
.alert {
|
||||
margin: 0.35em;
|
||||
padding: 0.25em;
|
||||
border-radius: $fallback--tooltipRadius;
|
||||
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
|
||||
color: $fallback--faint;
|
||||
color: var(--faint, $fallback--faint);
|
||||
min-height: 28px;
|
||||
line-height: 28px;
|
||||
|
||||
&.error {
|
||||
background-color: $fallback--cAlertRed;
|
||||
background-color: var(--cAlertRed, $fallback--cAlertRed);
|
||||
}
|
||||
}
|
||||
|
||||
.faint {
|
||||
color: $fallback--faint;
|
||||
color: var(--faint, $fallback--faint);
|
||||
}
|
||||
|
||||
@media all and (max-width: 959px) {
|
||||
.mobile-hidden {
|
||||
display: none;
|
||||
}
|
||||
.mobile-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.panel-switcher {
|
||||
display: flex;
|
||||
}
|
||||
.panel-switcher {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
.container {
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
|
||||
.panel {
|
||||
margin: 0.5em 0 0.5em 0;
|
||||
}
|
||||
.panel {
|
||||
margin: 0.5em 0 0.5em 0;
|
||||
}
|
||||
}
|
||||
|
||||
.item.right {
|
||||
text-align: right;
|
||||
padding-right: 20px;
|
||||
text-align: right;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
|
10
src/App.vue
10
src/App.vue
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div id="app" v-bind:style="style" class="base02-background">
|
||||
<nav class='container base02-background base05' @click="scrollToTop()" id="nav">
|
||||
<div id="app" v-bind:style="style">
|
||||
<nav class='container' @click="scrollToTop()" id="nav">
|
||||
<div class='inner-nav' :style="logoStyle">
|
||||
<div class='item'>
|
||||
<router-link :to="{ name: 'root'}">{{sitename}}</router-link>
|
||||
|
@ -14,8 +14,8 @@
|
|||
</nav>
|
||||
<div class="container" id="content">
|
||||
<div class="panel-switcher">
|
||||
<button @click="activatePanel('sidebar')" class="base02-background base05">Sidebar</button>
|
||||
<button @click="activatePanel('timeline')" class="base02-background base05">Timeline</button>
|
||||
<button @click="activatePanel('sidebar')">Sidebar</button>
|
||||
<button @click="activatePanel('timeline')">Timeline</button>
|
||||
</div>
|
||||
<div class="sidebar-flexer" :class="{ 'mobile-hidden': mobileActivePanel != 'sidebar'}">
|
||||
<div class="sidebar-bounds">
|
||||
|
@ -25,7 +25,6 @@
|
|||
<nav-panel></nav-panel>
|
||||
<instance-specific-panel v-if="showInstanceSpecificPanel"></instance-specific-panel>
|
||||
<who-to-follow-panel v-if="currentUser && showWhoToFollowPanel"></who-to-follow-panel>
|
||||
<chat-panel v-if="currentUser && chat"></chat-panel>
|
||||
<notifications v-if="currentUser"></notifications>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -37,6 +36,7 @@
|
|||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
<chat-panel v-if="currentUser && chat" class="floating-chat mobile-hidden"></chat-panel>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,7 +1,27 @@
|
|||
$main-color: #f58d2c;
|
||||
$main-background: white;
|
||||
$darkened-background: whitesmoke;
|
||||
$green: #0fa00f;
|
||||
$blue: #0095ff;
|
||||
$red: #ff0000;
|
||||
|
||||
$fallback--bg: #121a24;
|
||||
$fallback--btn: #182230;
|
||||
$fallback--faint: #999;
|
||||
$fallback--fg: #b9b9ba;
|
||||
$fallback--link: #d8a070;
|
||||
$fallback--icon: #666;
|
||||
$fallback--lightBg: rgb(21, 30, 42);
|
||||
$fallback--lightFg: #b9b9ba;
|
||||
$fallback--border: #222;
|
||||
$fallback--cRed: #ff0000;
|
||||
$fallback--cBlue: #0095ff;
|
||||
$fallback--cGreen: #0fa00f;
|
||||
$fallback--cOrange: orange;
|
||||
|
||||
$fallback--cAlertRed: rgba(211,16,20,.5);
|
||||
|
||||
$fallback--panelRadius: 10px;
|
||||
$fallback--checkBoxRadius: 2px;
|
||||
$fallback--btnRadius: 4px;
|
||||
$fallback--tooltipRadius: 5px;
|
||||
$fallback--avatarRadius: 4px;
|
||||
$fallback--avatarAltRadius: 10px;
|
||||
$fallback--attachmentRadius: 10px;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import StillImage from '../still-image/still-image.vue'
|
||||
import nsfwImage from '../../assets/nsfw.png'
|
||||
import fileTypeService from '../../services/file_type/file_type.service.js'
|
||||
|
||||
|
@ -5,7 +6,8 @@ const Attachment = {
|
|||
props: [
|
||||
'attachment',
|
||||
'nsfw',
|
||||
'statusId'
|
||||
'statusId',
|
||||
'size'
|
||||
],
|
||||
data () {
|
||||
return {
|
||||
|
@ -16,6 +18,9 @@ const Attachment = {
|
|||
img: document.createElement('img')
|
||||
}
|
||||
},
|
||||
components: {
|
||||
StillImage
|
||||
},
|
||||
computed: {
|
||||
type () {
|
||||
return fileTypeService.fileType(this.attachment.mimetype)
|
||||
|
@ -25,6 +30,12 @@ const Attachment = {
|
|||
},
|
||||
isEmpty () {
|
||||
return (this.type === 'html' && !this.attachment.oembed) || this.type === 'unknown'
|
||||
},
|
||||
isSmall () {
|
||||
return this.size === 'small'
|
||||
},
|
||||
fullwidth () {
|
||||
return fileTypeService.fileType(this.attachment.mimetype) === 'html'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<template>
|
||||
<div class="attachment base03-border" :class="{[type]: true, loading}" v-show="!isEmpty">
|
||||
<div v-if="size==='hide'">
|
||||
<a class="placeholder" v-if="type !== 'html'" target="_blank" :href="attachment.url">[{{nsfw ? "NSFW/" : ""}}{{type.toUpperCase()}}]</a>
|
||||
</div>
|
||||
<div v-else class="attachment" :class="{[type]: true, loading, 'small-attachment': isSmall, 'fullwidth': fullwidth}" v-show="!isEmpty">
|
||||
<a class="image-attachment" v-if="hidden" @click.prevent="toggleHidden()">
|
||||
<img :key="nsfwImage" :src="nsfwImage"/>
|
||||
</a>
|
||||
|
@ -8,10 +11,10 @@
|
|||
</div>
|
||||
|
||||
<a v-if="type === 'image' && !hidden" class="image-attachment" :href="attachment.url" target="_blank">
|
||||
<img class="base03-border" referrerpolicy="no-referrer" :src="attachment.large_thumb_url || attachment.url"/>
|
||||
<StillImage :class="{'small': isSmall}" referrerpolicy="no-referrer" :mimetype="attachment.mimetype" :src="attachment.large_thumb_url || attachment.url"/>
|
||||
</a>
|
||||
|
||||
<video class="base03" v-if="type === 'video' && !hidden" :src="attachment.url" controls loop></video>
|
||||
<video :class="{'small': isSmall}" v-if="type === 'video' && !hidden" :src="attachment.url" controls loop></video>
|
||||
|
||||
<audio v-if="type === 'audio'" :src="attachment.url" controls></audio>
|
||||
|
||||
|
@ -30,110 +33,145 @@
|
|||
<script src="./attachment.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
.attachments {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-right: -0.7em;
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.attachment.media-upload-container {
|
||||
flex: 0 0 auto;
|
||||
max-height: 300px;
|
||||
max-width: 100%;
|
||||
.attachments {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-right: -0.7em;
|
||||
|
||||
.attachment.media-upload-container {
|
||||
flex: 0 0 auto;
|
||||
max-height: 300px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.small-attachment {
|
||||
&.image, &.video {
|
||||
max-width: 35%;
|
||||
}
|
||||
max-height: 100px;
|
||||
}
|
||||
|
||||
.attachment {
|
||||
flex: 1 0 30%;
|
||||
margin: 0.5em 0.7em 0.6em 0.0em;
|
||||
align-self: flex-start;
|
||||
line-height: 0;
|
||||
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: $fallback--attachmentRadius;
|
||||
border-radius: var(--attachmentRadius, $fallback--attachmentRadius);
|
||||
border-color: $fallback--border;
|
||||
border-color: var(--border, $fallback--border);
|
||||
overflow: hidden;
|
||||
}
|
||||
.fullwidth {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
// fixes small gap below video
|
||||
&.video {
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
&.html {
|
||||
flex-basis: 90%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&.loading {
|
||||
cursor: progress;
|
||||
}
|
||||
|
||||
.hider {
|
||||
position: absolute;
|
||||
margin: 10px;
|
||||
padding: 5px;
|
||||
background: rgba(230,230,230,0.6);
|
||||
font-weight: bold;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.small {
|
||||
max-height: 100px;
|
||||
}
|
||||
video {
|
||||
max-height: 500px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
audio {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
img.media-upload {
|
||||
line-height: 0;
|
||||
max-height: 300px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.oembed {
|
||||
line-height: 1.2em;
|
||||
flex: 1 0 100%;
|
||||
width: 100%;
|
||||
margin-right: 15px;
|
||||
display: flex;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.image {
|
||||
flex: 1;
|
||||
img {
|
||||
border: 0px;
|
||||
border-radius: 5px;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.attachment {
|
||||
flex: 1 0 30%;
|
||||
margin: 0.5em 0.7em 0.6em 0.0em;
|
||||
align-self: flex-start;
|
||||
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
|
||||
// fixes small gap below video
|
||||
&.video {
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
&.html {
|
||||
flex-basis: 90%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&.loading {
|
||||
cursor: progress;
|
||||
}
|
||||
|
||||
.hider {
|
||||
position: absolute;
|
||||
margin: 10px;
|
||||
padding: 5px;
|
||||
background: rgba(230,230,230,0.6);
|
||||
font-weight: bold;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
video {
|
||||
max-height: 500px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
audio {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
img.media-upload {
|
||||
margin-bottom: -2px;
|
||||
max-height: 300px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.oembed {
|
||||
width: 100%;
|
||||
margin-right: 15px;
|
||||
display: flex;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.image {
|
||||
flex: 1;
|
||||
img {
|
||||
border: 0px;
|
||||
border-radius: 5px;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
flex: 2;
|
||||
margin: 8px;
|
||||
word-break: break-all;
|
||||
h1 {
|
||||
font-size: 14px;
|
||||
margin: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a.image-attachment {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
||||
img {
|
||||
object-fit: contain;
|
||||
width: 100%;
|
||||
height: 100%; /* If this isn't here, chrome will stretch the images */
|
||||
max-height: 500px;
|
||||
image-orientation: from-image;
|
||||
}
|
||||
}
|
||||
.text {
|
||||
flex: 2;
|
||||
margin: 8px;
|
||||
word-break: break-all;
|
||||
h1 {
|
||||
font-size: 14px;
|
||||
margin: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.image-attachment {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
||||
.still-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.small {
|
||||
img {
|
||||
max-height: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
object-fit: contain;
|
||||
width: 100%;
|
||||
height: 100%; /* If this isn't here, chrome will stretch the images */
|
||||
max-height: 500px;
|
||||
image-orientation: from-image;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -2,7 +2,8 @@ const chatPanel = {
|
|||
data () {
|
||||
return {
|
||||
currentMessage: '',
|
||||
channel: null
|
||||
channel: null,
|
||||
collapsed: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -14,6 +15,9 @@ const chatPanel = {
|
|||
submit (message) {
|
||||
this.$store.state.chat.channel.push('new_msg', {text: message}, 10000)
|
||||
this.currentMessage = ''
|
||||
},
|
||||
togglePanel () {
|
||||
this.collapsed = !this.collapsed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,40 @@
|
|||
<template>
|
||||
<div class="chat-panel">
|
||||
<div class="panel panel-default base01-background">
|
||||
<div class="panel-heading timeline-heading base02-background base04">
|
||||
<div class="chat-panel" v-if="!this.collapsed">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading timeline-heading chat-heading" @click.stop.prevent="togglePanel">
|
||||
<div class="title">
|
||||
{{$t('chat.title')}}
|
||||
<i class="icon-cancel" style="float: right;"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-window" v-chat-scroll>
|
||||
<div class="chat-message" v-for="message in messages" :key="message.id">
|
||||
<span class="chat-avatar">
|
||||
<img :src="message.author.avatar" />
|
||||
{{message.author.username}}:
|
||||
</span>
|
||||
<span class="chat-text">
|
||||
{{message.text}}
|
||||
</span>
|
||||
<div class="chat-content">
|
||||
<router-link class="chat-name" :to="{ name: 'user-profile', params: { id: message.author.id } }">
|
||||
{{message.author.username}}
|
||||
</router-link>
|
||||
<br>
|
||||
<span class="chat-text">
|
||||
{{message.text}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-input">
|
||||
<form @submit.prevent="submit(currentMessage)">
|
||||
<input v-model="currentMessage" type="text" >
|
||||
</form>
|
||||
<textarea @keyup.enter="submit(currentMessage)" v-model="currentMessage" class="chat-input-textarea" rows="1"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="chat-panel">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading stub timeline-heading chat-heading" @click.stop.prevent="togglePanel">
|
||||
<div class="title">
|
||||
<i class="icon-comment-empty"></i>
|
||||
{{$t('chat.title')}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -29,30 +43,56 @@
|
|||
<script src="./chat_panel.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
.chat-window {
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
.chat-message {
|
||||
padding: 0.2em 0.5em
|
||||
}
|
||||
.chat-avatar {
|
||||
img {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
border-radius: 5px;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
}
|
||||
.chat-input {
|
||||
display: flex;
|
||||
form {
|
||||
flex: auto;
|
||||
input {
|
||||
margin: 0.5em;
|
||||
width: fill-available;
|
||||
}
|
||||
}
|
||||
}
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.floating-chat {
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.chat-heading {
|
||||
cursor: pointer;
|
||||
.icon-comment-empty {
|
||||
color: $fallback--fg;
|
||||
color: var(--fg, $fallback--fg);
|
||||
}
|
||||
}
|
||||
|
||||
.chat-window {
|
||||
width: 345px;
|
||||
max-height: 40vh;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.chat-name {
|
||||
}
|
||||
|
||||
.chat-message {
|
||||
display: flex;
|
||||
padding: 0.2em 0.5em
|
||||
}
|
||||
|
||||
.chat-avatar {
|
||||
img {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
border-radius: $fallback--avatarRadius;
|
||||
border-radius: var(--avatarRadius, $fallback--avatarRadius);
|
||||
margin-right: 0.5em;
|
||||
margin-top: 0.25em;
|
||||
}
|
||||
}
|
||||
|
||||
.chat-input {
|
||||
display: flex;
|
||||
textarea {
|
||||
flex: 1;
|
||||
margin: 0.6em;
|
||||
min-height: 3.5em;
|
||||
resize: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="timeline panel panel-default">
|
||||
<div class="panel-heading base02-background base04 base03-border conversation-heading">
|
||||
<div class="panel-heading conversation-heading">
|
||||
{{ $t('timeline.conversation') }}
|
||||
<span v-if="collapsable" style="float:right;">
|
||||
<small><a href="#" @click.prevent="$emit('toggleExpanded')">Collapse</a></small>
|
||||
|
@ -8,7 +8,16 @@
|
|||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="timeline">
|
||||
<status v-for="status in conversation" @goto="setHighlight" :key="status.id" :statusoid="status" :expandable='false' :focused="focused(status.id)" :inConversation='true' :highlight="highlight" :replies="getReplies(status.id)"></status>
|
||||
<status
|
||||
v-for="status in conversation"
|
||||
@goto="setHighlight" :key="status.id"
|
||||
:inlineExpanded="collapsable" :statusoid="status"
|
||||
:expandable='false' :focused="focused(status.id)"
|
||||
:inConversation='true'
|
||||
:highlight="highlight"
|
||||
:replies="getReplies(status.id)"
|
||||
class="status-fadein">
|
||||
</status>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -10,7 +10,7 @@ const DeleteButton = {
|
|||
},
|
||||
computed: {
|
||||
currentUser () { return this.$store.state.users.currentUser },
|
||||
canDelete () { return this.currentUser.rights.delete_others_notice || this.status.user.id === this.currentUser.id }
|
||||
canDelete () { return this.currentUser && this.currentUser.rights.delete_others_notice || this.status.user.id === this.currentUser.id }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
<template>
|
||||
<div v-if="canDelete">
|
||||
<a href="#" v-on:click.prevent="deleteStatus()">
|
||||
<i class='base09 icon-cancel delete-status'></i>
|
||||
<i class='icon-cancel delete-status'></i>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./delete_button.js" ></script>
|
||||
|
||||
<style lang='scss'>
|
||||
@import '../../_variables.scss';
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.icon-cancel,.delete-status {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: $red;
|
||||
}
|
||||
.icon-cancel,.delete-status {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: var(--cRed, $fallback--cRed);
|
||||
color: $fallback--cRed;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,26 +1,31 @@
|
|||
<template>
|
||||
<div v-if="loggedIn">
|
||||
<i :class='classes' class='favorite-button fav-active base09' @click.prevent='favorite()'/>
|
||||
<i :class='classes' class='favorite-button fav-active' @click.prevent='favorite()'/>
|
||||
<span v-if='status.fave_num > 0'>{{status.fave_num}}</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<i :class='classes' class='favorite-button base09'/>
|
||||
<i :class='classes' class='favorite-button'/>
|
||||
<span v-if='status.fave_num > 0'>{{status.fave_num}}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./favorite_button.js" ></script>
|
||||
|
||||
<style lang='scss'>
|
||||
.fav-active {
|
||||
cursor: pointer;
|
||||
animation-duration: 0.6s;
|
||||
&:hover {
|
||||
color: orange;
|
||||
}
|
||||
}
|
||||
.favorite-button.icon-star {
|
||||
color: orange;
|
||||
}
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.fav-active {
|
||||
cursor: pointer;
|
||||
animation-duration: 0.6s;
|
||||
|
||||
&:hover {
|
||||
color: $fallback--cOrange;
|
||||
color: var(--cOrange, $fallback--cOrange);
|
||||
}
|
||||
}
|
||||
|
||||
.favorite-button.icon-star {
|
||||
color: $fallback--cOrange;
|
||||
color: var(--cOrange, $fallback--cOrange);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="instance-specific-panel">
|
||||
<div class="panel panel-default base01-background">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<div v-html="instanceSpecificPanelContent">
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="login panel panel-default base00-background">
|
||||
<div class="login panel panel-default">
|
||||
<!-- Default panel contents -->
|
||||
<div class="panel-heading base02-background base04">
|
||||
<div class="panel-heading">
|
||||
{{$t('login.login')}}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
@ -17,11 +17,11 @@
|
|||
<div class='form-group'>
|
||||
<div class='login-bottom'>
|
||||
<div><router-link :to="{name: 'registration'}" v-if='registrationOpen' class='register'>{{$t('login.register')}}</router-link></div>
|
||||
<button :disabled="loggingIn" type='submit' class='btn btn-default base04 base02-background'>{{$t('login.login')}}</button>
|
||||
<button :disabled="loggingIn" type='submit' class='btn btn-default'>{{$t('login.login')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="authError" class='form-group'>
|
||||
<div class='error base05'>{{authError}}</div>
|
||||
<div class='alert error'>{{authError}}</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -31,27 +31,16 @@
|
|||
<script src="./login_form.js" ></script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.login-form {
|
||||
input {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: silver;
|
||||
border-radius: 5px;
|
||||
padding: 0.1em 0.2em 0.2em 0.2em;
|
||||
}
|
||||
|
||||
.btn {
|
||||
min-height: 28px;
|
||||
width: 10em;
|
||||
}
|
||||
|
||||
.error {
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
background-color: rgba(255, 48, 16, 0.65);
|
||||
min-height: 28px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.register {
|
||||
|
@ -66,5 +55,4 @@
|
|||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<div class="media-upload" @drop.prevent @dragover.prevent="fileDrag" @drop="fileDrop">
|
||||
<label class="btn btn-default">
|
||||
<i class="base09 icon-spin4 animate-spin" v-if="uploading"></i>
|
||||
<i class="base09 icon-upload" v-if="!uploading"></i>
|
||||
<i class="icon-spin4 animate-spin" v-if="uploading"></i>
|
||||
<i class="icon-upload" v-if="!uploading"></i>
|
||||
<input type=file style="position: fixed; top: -100em"></input>
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
<template>
|
||||
<div class="nav-panel">
|
||||
<div class="panel panel-default base01-background">
|
||||
<ul class="base03-border">
|
||||
<div class="panel panel-default">
|
||||
<ul>
|
||||
<li v-if='currentUser'>
|
||||
<router-link class="base00-background" to='/main/friends'>
|
||||
<router-link to='/main/friends'>
|
||||
{{ $t("nav.timeline") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li v-if='currentUser'>
|
||||
<router-link class="base00-background" :to="{ name: 'mentions', params: { username: currentUser.screen_name } }">
|
||||
<router-link :to="{ name: 'mentions', params: { username: currentUser.screen_name } }">
|
||||
{{ $t("nav.mentions") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link class="base00-background" to='/main/public'>
|
||||
<router-link to='/main/public'>
|
||||
{{ $t("nav.public_tl") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link class="base00-background" to='/main/all'>
|
||||
<router-link to='/main/all'>
|
||||
{{ $t("nav.twkn") }}
|
||||
</router-link>
|
||||
</li>
|
||||
|
@ -30,43 +30,61 @@
|
|||
<script src="./nav_panel.js" ></script>
|
||||
|
||||
<style lang="scss">
|
||||
.nav-panel ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.nav-panel li {
|
||||
border-bottom: 1px solid;
|
||||
border-color: inherit;
|
||||
padding: 0;
|
||||
&:first-child a {
|
||||
border-top-right-radius: 10px;
|
||||
border-top-left-radius: 10px;
|
||||
}
|
||||
&:last-child a {
|
||||
border-bottom-right-radius: 10px;
|
||||
border-bottom-left-radius: 10px;
|
||||
}
|
||||
}
|
||||
.nav-panel .panel {
|
||||
overflow: hidden;
|
||||
}
|
||||
.nav-panel ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.nav-panel li:last-child {
|
||||
border: none;
|
||||
}
|
||||
.nav-panel li {
|
||||
border-bottom: 1px solid;
|
||||
border-color: $fallback--border;
|
||||
border-color: var(--border, $fallback--border);
|
||||
background-color: $fallback--bg;
|
||||
background-color: var(--bg, $fallback--bg);
|
||||
padding: 0;
|
||||
|
||||
.nav-panel a {
|
||||
display: block;
|
||||
padding: 0.8em 0.85em;
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
&.router-link-active {
|
||||
font-weight: bolder;
|
||||
background-color: transparent;
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:first-child a {
|
||||
border-top-right-radius: $fallback--panelRadius;
|
||||
border-top-right-radius: var(--panelRadius, $fallback--panelRadius);
|
||||
border-top-left-radius: $fallback--panelRadius;
|
||||
border-top-left-radius: var(--panelRadius, $fallback--panelRadius);
|
||||
}
|
||||
|
||||
&:last-child a {
|
||||
border-bottom-right-radius: $fallback--panelRadius;
|
||||
border-bottom-right-radius: var(--panelRadius, $fallback--panelRadius);
|
||||
border-bottom-left-radius: $fallback--panelRadius;
|
||||
border-bottom-left-radius: var(--panelRadius, $fallback--panelRadius);
|
||||
}
|
||||
}
|
||||
|
||||
.nav-panel li:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.nav-panel a {
|
||||
display: block;
|
||||
padding: 0.8em 0.85em;
|
||||
|
||||
&:hover {
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--lightBg, $fallback--lightBg);
|
||||
}
|
||||
|
||||
&.router-link-active {
|
||||
font-weight: bolder;
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--lightBg, $fallback--lightBg);
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
24
src/components/notification/notification.js
Normal file
24
src/components/notification/notification.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import Status from '../status/status.vue'
|
||||
import StillImage from '../still-image/still-image.vue'
|
||||
import UserCardContent from '../user_card_content/user_card_content.vue'
|
||||
|
||||
const Notification = {
|
||||
data () {
|
||||
return {
|
||||
userExpanded: false
|
||||
}
|
||||
},
|
||||
props: [
|
||||
'notification'
|
||||
],
|
||||
components: {
|
||||
Status, StillImage, UserCardContent
|
||||
},
|
||||
methods: {
|
||||
toggleUserExpanded () {
|
||||
this.userExpanded = !this.userExpanded
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Notification
|
37
src/components/notification/notification.vue
Normal file
37
src/components/notification/notification.vue
Normal file
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<status v-if="notification.type === 'mention'" :compact="true" :statusoid="notification.status"></status>
|
||||
<div class="non-mention" v-else>
|
||||
<a class='avatar-container' :href="notification.action.user.statusnet_profile_url" @click.stop.prevent.capture="toggleUserExpanded">
|
||||
<StillImage class='avatar-compact' :src="notification.action.user.profile_image_url_original"/>
|
||||
</a>
|
||||
<div class='notification-right'>
|
||||
<div class="usercard notification-usercard" v-if="userExpanded">
|
||||
<user-card-content :user="notification.action.user" :switcher="false"></user-card-content>
|
||||
</div>
|
||||
<span class="notification-details">
|
||||
<div class="name-and-action">
|
||||
<span class="username" :title="'@'+notification.action.user.screen_name">{{ notification.action.user.name }}</span>
|
||||
<span v-if="notification.type === 'favorite'">
|
||||
<i class="fa icon-star lit"></i>
|
||||
<small>{{$t('notifications.favorited_you')}}</small>
|
||||
</span>
|
||||
<span v-if="notification.type === 'repeat'">
|
||||
<i class="fa icon-retweet lit"></i>
|
||||
<small>{{$t('notifications.repeated_you')}}</small>
|
||||
</span>
|
||||
<span v-if="notification.type === 'follow'">
|
||||
<i class="fa icon-user-plus lit"></i>
|
||||
<small>{{$t('notifications.followed_you')}}</small>
|
||||
</span>
|
||||
</div>
|
||||
<small class="timeago"><router-link :to="{ name: 'conversation', params: { id: notification.status.id } }"><timeago :since="notification.action.created_at" :auto-update="240"></timeago></router-link></small>
|
||||
</span>
|
||||
<div class="follow-text" v-if="notification.type === 'follow'">
|
||||
<router-link :to="{ name: 'user-profile', params: { id: notification.action.user.id } }">@{{notification.action.user.screen_name}}</router-link>
|
||||
</div>
|
||||
<status v-else class="faint" :compact="true" :statusoid="notification.status" :noHeading="true"></status>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./notification.js"></script>
|
|
@ -1,11 +1,11 @@
|
|||
import Status from '../status/status.vue'
|
||||
import Notification from '../notification/notification.vue'
|
||||
|
||||
import { sortBy, take, filter } from 'lodash'
|
||||
|
||||
const Notifications = {
|
||||
data () {
|
||||
return {
|
||||
visibleNotificationCount: 10
|
||||
visibleNotificationCount: 20
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -23,15 +23,10 @@ const Notifications = {
|
|||
},
|
||||
unseenCount () {
|
||||
return this.unseenNotifications.length
|
||||
},
|
||||
hiderStyle () {
|
||||
return {
|
||||
background: `linear-gradient(to bottom, rgba(0, 0, 0, 0), ${this.$store.state.config.colors['base00']} 80%)`
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Status
|
||||
Notification
|
||||
},
|
||||
watch: {
|
||||
unseenCount (count) {
|
||||
|
|
|
@ -4,10 +4,24 @@
|
|||
// a bit of a hack to allow scrolling below notifications
|
||||
padding-bottom: 15em;
|
||||
|
||||
.panel {
|
||||
background: $fallback--bg;
|
||||
background: var(--bg, $fallback--bg)
|
||||
}
|
||||
|
||||
.panel-body {
|
||||
border-color: $fallback--border;
|
||||
border-color: var(--border, $fallback--border)
|
||||
}
|
||||
|
||||
.panel-heading {
|
||||
// force the text to stay centered, while keeping
|
||||
// the button in the right side of the panel heading
|
||||
position: relative;
|
||||
background: $fallback--btn;
|
||||
background: var(--btn, $fallback--btn);
|
||||
color: $fallback--fg;
|
||||
color: var(--fg, $fallback--fg);
|
||||
.read-button {
|
||||
position: absolute;
|
||||
right: 0.7em;
|
||||
|
@ -18,7 +32,8 @@
|
|||
|
||||
.unseen-count {
|
||||
display: inline-block;
|
||||
background-color: rgba(255, 16, 8, 0.8);
|
||||
background-color: $fallback--cRed;
|
||||
background-color: var(--cRed, $fallback--cRed);
|
||||
text-shadow: 0px 0px 3px rgba(0, 0, 0, 0.5);
|
||||
min-width: 1.3em;
|
||||
border-radius: 1.3em;
|
||||
|
@ -29,92 +44,167 @@
|
|||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
.notification {
|
||||
// Will have to use pixels here to ensure consistent distance with
|
||||
// pad alone and pad + border, browsers bad at rounding this with em,
|
||||
// they love to give a 1 pixel ghost offset with 0.7em vs 0.3em + 0.4em,
|
||||
// which does not happen with 10px vs 4px + 6px.
|
||||
padding: 0.4em 0 0 10px;
|
||||
display: flex;
|
||||
border-bottom: 1px solid;
|
||||
border-bottom-color: inherit;
|
||||
|
||||
|
||||
.text {
|
||||
min-width: 0px;
|
||||
word-wrap: break-word;
|
||||
line-height:18px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.icon-retweet.lit {
|
||||
color: $green;
|
||||
}
|
||||
|
||||
.icon-user-plus.lit {
|
||||
color: $blue;
|
||||
}
|
||||
|
||||
.icon-reply.lit {
|
||||
color: $blue;
|
||||
}
|
||||
|
||||
.icon-star.lit {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
.status-content {
|
||||
margin: 0;
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
word-break: break-all;
|
||||
margin: 0 0 0.3em;
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
line-height:20px;
|
||||
small {
|
||||
font-weight: lighter;
|
||||
}
|
||||
}
|
||||
|
||||
padding: 0.3em 0.8em 0.5em;
|
||||
p {
|
||||
margin: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar {
|
||||
padding-top: 0.3em;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
border-radius: 0 0 10px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.notification-content {
|
||||
max-height: 12em;
|
||||
overflow-y: hidden;
|
||||
//text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.notification-gradient {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 4em;
|
||||
margin-top:8em;
|
||||
}
|
||||
|
||||
.unseen {
|
||||
border-left: 4px solid rgba(255, 16, 8, 0.75);
|
||||
padding-left: 6px;
|
||||
border-left: 4px solid $fallback--cRed;
|
||||
border-left: 4px solid var(--cRed, $fallback--cRed);
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.notification {
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
border-bottom: 1px solid;
|
||||
border-bottom-color: inherit;
|
||||
padding-left: 4px;
|
||||
|
||||
.avatar-compact {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: $fallback--avatarAltRadius;
|
||||
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
|
||||
overflow: hidden;
|
||||
line-height: 0;
|
||||
|
||||
&.animated::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .animated.avatar {
|
||||
canvas {
|
||||
display: none;
|
||||
}
|
||||
img {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.notification-usercard {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.non-mention {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-wrap: nowrap;
|
||||
padding: 0.6em;
|
||||
min-width: 0;
|
||||
.avatar-container {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
.status-el {
|
||||
.status {
|
||||
padding: 0.25em 0;
|
||||
color: $fallback--faint;
|
||||
color: var($fallback--faint, --faint);
|
||||
}
|
||||
padding: 0;
|
||||
.media-body {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.follow-text {
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
|
||||
.status-el {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
time {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.notification-right {
|
||||
flex: 1;
|
||||
padding-left: 0.8em;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.notification-details {
|
||||
min-width: 0px;
|
||||
word-wrap: break-word;
|
||||
line-height:18px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
flex: 1 1 0;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
.name-and-action {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.username {
|
||||
font-weight: bolder;
|
||||
max-width: 100%;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.timeago {
|
||||
float: right;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.icon-retweet.lit {
|
||||
color: $fallback--cGreen;
|
||||
color: var(--cGreen, $fallback--cGreen);
|
||||
}
|
||||
|
||||
.icon-user-plus.lit {
|
||||
color: $fallback--cBlue;
|
||||
color: var(--cBlue, $fallback--cBlue);
|
||||
}
|
||||
|
||||
.icon-reply.lit {
|
||||
color: $fallback--cBlue;
|
||||
color: var(--cBlue, $fallback--cBlue);
|
||||
}
|
||||
|
||||
.icon-star.lit {
|
||||
color: orange;
|
||||
color: $fallback--cOrange;
|
||||
color: var(--cOrange, $fallback--cOrange);
|
||||
}
|
||||
|
||||
.status-content {
|
||||
margin: 0;
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
word-break: break-all;
|
||||
margin: 0 0 0.3em;
|
||||
padding: 0;
|
||||
font-size: 1em;
|
||||
line-height:20px;
|
||||
small {
|
||||
font-weight: lighter;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
}
|
||||
|
||||
// ugly as heck
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;
|
||||
border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
|
||||
.status-el {
|
||||
border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;
|
||||
border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,55 +1,14 @@
|
|||
<template>
|
||||
<div class="notifications">
|
||||
<div class="panel panel-default base00-background">
|
||||
<div class="panel-heading base02-background base04">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<span class="unseen-count" v-if="unseenCount">{{unseenCount}}</span>
|
||||
{{$t('notifications.notifications')}}
|
||||
<button v-if="unseenCount" @click.prevent="markAsSeen" class="base04 base02-background read-button">{{$t('notifications.read')}}</button>
|
||||
<button v-if="unseenCount" @click.prevent="markAsSeen" class="read-button">{{$t('notifications.read')}}</button>
|
||||
</div>
|
||||
<div class="panel-body base03-border">
|
||||
<div v-for="notification in visibleNotifications" :key="notification" class="notification" :class='{"unseen": !notification.seen}'>
|
||||
<div>
|
||||
<a :href="notification.action.user.statusnet_profile_url" target="_blank">
|
||||
<img class='avatar' :src="notification.action.user.profile_image_url_original">
|
||||
</a>
|
||||
</div>
|
||||
<div class='text' style="width: 100%;">
|
||||
<div v-if="notification.type === 'favorite'">
|
||||
<h1>
|
||||
<span :title="'@'+notification.action.user.screen_name">{{ notification.action.user.name }}</span>
|
||||
<i class="fa icon-star lit"></i>
|
||||
<small><router-link :to="{ name: 'conversation', params: { id: notification.status.id } }"><timeago :since="notification.action.created_at" :auto-update="240"></timeago></router-link></small>
|
||||
</h1>
|
||||
<div class="notification-gradient" :style="hiderStyle"></div>
|
||||
<div class="notification-content" v-html="notification.status.statusnet_html"></div>
|
||||
</div>
|
||||
<div v-if="notification.type === 'repeat'">
|
||||
<h1>
|
||||
<span :title="'@'+notification.action.user.screen_name">{{ notification.action.user.name }}</span>
|
||||
<i class="fa icon-retweet lit"></i>
|
||||
<small><router-link :to="{ name: 'conversation', params: { id: notification.status.id } }"><timeago :since="notification.action.created_at" :auto-update="240"></timeago></router-link></small>
|
||||
</h1>
|
||||
<div class="notification-gradient" :style="hiderStyle"></div>
|
||||
<div class="notification-content" v-html="notification.status.statusnet_html"></div>
|
||||
</div>
|
||||
<div v-if="notification.type === 'mention'">
|
||||
<h1>
|
||||
<span :title="'@'+notification.action.user.screen_name">{{ notification.action.user.name }}</span>
|
||||
<i class="fa icon-reply lit"></i>
|
||||
<small><router-link :to="{ name: 'conversation', params: { id: notification.status.id } }"><timeago :since="notification.action.created_at" :auto-update="240"></timeago></router-link></small>
|
||||
</h1>
|
||||
<status :compact="true" :statusoid="notification.status"></status>
|
||||
</div>
|
||||
<div v-if="notification.type === 'follow'">
|
||||
<h1>
|
||||
<span :title="'@'+notification.action.user.screen_name">{{ notification.action.user.name }}</span>
|
||||
<i class="fa icon-user-plus lit"></i>
|
||||
</h1>
|
||||
<div>
|
||||
<router-link :to="{ name: 'user-profile', params: { id: notification.action.user.id } }">@{{ notification.action.user.screen_name }}</router-link> {{$t('notifications.followed_you')}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div v-for="notification in visibleNotifications" :key="notification.action.id" class="notification" :class='{"unseen": !notification.seen}'>
|
||||
<notification :notification="notification"></notification>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -28,6 +28,9 @@ const PostStatusForm = {
|
|||
components: {
|
||||
MediaUpload
|
||||
},
|
||||
mounted () {
|
||||
this.resize(this.$refs.textarea)
|
||||
},
|
||||
data () {
|
||||
let statusText = ''
|
||||
|
||||
|
@ -53,7 +56,8 @@ const PostStatusForm = {
|
|||
candidates () {
|
||||
const firstchar = this.textAtCaret.charAt(0)
|
||||
if (firstchar === '@') {
|
||||
const matchedUsers = filter(this.users, (user) => (String(user.name + user.screen_name)).match(this.textAtCaret.slice(1)))
|
||||
const matchedUsers = filter(this.users, (user) => (String(user.name + user.screen_name)).toUpperCase()
|
||||
.match(this.textAtCaret.slice(1).toUpperCase()))
|
||||
if (matchedUsers.length <= 0) {
|
||||
return false
|
||||
}
|
||||
|
@ -234,10 +238,14 @@ const PostStatusForm = {
|
|||
e.dataTransfer.dropEffect = 'copy'
|
||||
},
|
||||
resize (e) {
|
||||
e.target.style.height = 'auto'
|
||||
e.target.style.height = `${e.target.scrollHeight - 10}px`
|
||||
if (e.target.value === '') {
|
||||
e.target.style.height = '16px'
|
||||
const target = e.target || e
|
||||
target.style.height = 'auto'
|
||||
const heightPx = target.scrollHeight - 10
|
||||
if (heightPx > 54) {
|
||||
target.style.height = `${target.scrollHeight - 10}px`
|
||||
}
|
||||
if (target.value === '') {
|
||||
target.style.height = '16px'
|
||||
}
|
||||
},
|
||||
clearError () {
|
||||
|
|
|
@ -1,21 +1,36 @@
|
|||
<template>
|
||||
<div class="post-status-form">
|
||||
<form @submit.prevent="postStatus(newStatus)">
|
||||
<div class="form-group base03-border" >
|
||||
<textarea @click="setCaret" @keyup="setCaret" v-model="newStatus.status" :placeholder="$t('post_status.default')" rows="1" class="form-control" @keydown.down="cycleForward" @keydown.up="cycleBackward" @keydown.shift.tab="cycleBackward" @keydown.tab="cycleForward" @keydown.enter="replaceCandidate" @keydown.meta.enter="postStatus(newStatus)" @keyup.ctrl.enter="postStatus(newStatus)" @drop="fileDrop" @dragover.prevent="fileDrag" @input="resize" @paste="paste"></textarea>
|
||||
</div>
|
||||
<div style="position:relative;" v-if="candidates">
|
||||
<div class="autocomplete-panel base05-background">
|
||||
<div class="post-status-form">
|
||||
<form @submit.prevent="postStatus(newStatus)">
|
||||
<div class="form-group" >
|
||||
<textarea
|
||||
ref="textarea"
|
||||
@click="setCaret"
|
||||
@keyup="setCaret" v-model="newStatus.status" :placeholder="$t('post_status.default')" rows="1" class="form-control"
|
||||
@keydown.down="cycleForward"
|
||||
@keydown.up="cycleBackward"
|
||||
@keydown.shift.tab="cycleBackward"
|
||||
@keydown.tab="cycleForward"
|
||||
@keydown.enter="replaceCandidate"
|
||||
@keydown.meta.enter="postStatus(newStatus)"
|
||||
@keyup.ctrl.enter="postStatus(newStatus)"
|
||||
@drop="fileDrop"
|
||||
@dragover.prevent="fileDrag"
|
||||
@input="resize"
|
||||
@paste="paste">
|
||||
</textarea>
|
||||
</div>
|
||||
<div style="position:relative;" v-if="candidates">
|
||||
<div class="autocomplete-panel">
|
||||
<div v-for="candidate in candidates" @click="replace(candidate.utf || (candidate.screen_name + ' '))">
|
||||
<div v-if="candidate.highlighted" class="autocomplete base02">
|
||||
<div v-if="candidate.highlighted" class="autocomplete">
|
||||
<span v-if="candidate.img"><img :src="candidate.img"></span>
|
||||
<span v-else>{{candidate.utf}}</span>
|
||||
<span>{{candidate.screen_name}}<small class="base02">{{candidate.name}}</small></span>
|
||||
<span>{{candidate.screen_name}}<small>{{candidate.name}}</small></span>
|
||||
</div>
|
||||
<div v-else class="autocomplete base04">
|
||||
<div v-else class="autocomplete">
|
||||
<span v-if="candidate.img"><img :src="candidate.img"></img></span>
|
||||
<span v-else>{{candidate.utf}}</span>
|
||||
<span>{{candidate.screen_name}}<small class="base02">{{candidate.name}}</small></span>
|
||||
<span>{{candidate.screen_name}}<small>{{candidate.name}}</small></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -24,18 +39,18 @@
|
|||
<media-upload @uploading="disableSubmit" @uploaded="addMediaFile" @upload-failed="enableSubmit" :drop-files="dropFiles"></media-upload>
|
||||
|
||||
<p v-if="isOverLengthLimit" class="error">{{ charactersLeft }}</p>
|
||||
<p v-else-if="hasStatusLengthLimit" class="base04">{{ charactersLeft }}</p>
|
||||
<p class="faint" v-else-if="hasStatusLengthLimit">{{ charactersLeft }}</p>
|
||||
|
||||
<button v-if="posting" disabled class="btn btn-default base05 base02-background">{{$t('post_status.posting')}}</button>
|
||||
<button v-else-if="isOverLengthLimit" disabled class="btn btn-default base05 base02-background">{{$t('general.submit')}}</button>
|
||||
<button v-else :disabled="submitDisabled" type="submit" class="btn btn-default base05 base02-background">{{$t('general.submit')}}</button>
|
||||
<button v-if="posting" disabled class="btn btn-default">{{$t('post_status.posting')}}</button>
|
||||
<button v-else-if="isOverLengthLimit" disabled class="btn btn-default">{{$t('general.submit')}}</button>
|
||||
<button v-else :disabled="submitDisabled" type="submit" class="btn btn-default">{{$t('general.submit')}}</button>
|
||||
</div>
|
||||
<div class='error' v-if="error">
|
||||
<div class='alert error' v-if="error">
|
||||
Error: {{ error }}
|
||||
<i class="icon-cancel" @click="clearError"></i>
|
||||
</div>
|
||||
<div class="attachments">
|
||||
<div class="media-upload-container attachment base03-border" v-for="file in newStatus.files">
|
||||
<div class="media-upload-container attachment" v-for="file in newStatus.files">
|
||||
<i class="fa icon-cancel" @click="removeMediaFile(file)"></i>
|
||||
<img class="thumbnail media-upload" :src="file.image" v-if="type(file) === 'image'"></img>
|
||||
<video v-if="type(file) === 'video'" :src="file.image" controls></video>
|
||||
|
@ -50,147 +65,157 @@
|
|||
<script src="./post_status_form.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.tribute-container {
|
||||
ul {
|
||||
padding: 0px;
|
||||
li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
img {
|
||||
padding: 3px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.tribute-container {
|
||||
ul {
|
||||
padding: 0px;
|
||||
li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
img {
|
||||
padding: 3px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: $fallback--avatarAltRadius;
|
||||
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
|
||||
}
|
||||
}
|
||||
|
||||
.post-status-form, .login {
|
||||
.form-bottom {
|
||||
display: flex;
|
||||
padding: 0.5em;
|
||||
height: 32px;
|
||||
.post-status-form, .login {
|
||||
.form-bottom {
|
||||
display: flex;
|
||||
padding: 0.5em;
|
||||
height: 32px;
|
||||
|
||||
button {
|
||||
width: 10em;
|
||||
}
|
||||
button {
|
||||
width: 10em;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0.35em;
|
||||
padding: 0.35em;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
.error {
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
background-color: rgba(255, 48, 16, 0.65);
|
||||
padding: 0.25em;
|
||||
margin: 0.35em;
|
||||
display: flex;
|
||||
}
|
||||
p {
|
||||
margin: 0.35em;
|
||||
padding: 0.35em;
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.attachments {
|
||||
padding: 0 0.5em;
|
||||
.error {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.attachment {
|
||||
position: relative;
|
||||
margin: 0.5em 0.8em 0.2em 0;
|
||||
}
|
||||
.attachments {
|
||||
padding: 0 0.5em;
|
||||
|
||||
i {
|
||||
position: absolute;
|
||||
margin: 10px;
|
||||
padding: 5px;
|
||||
background: rgba(230,230,230,0.6);
|
||||
border-radius: 5px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.attachment {
|
||||
position: relative;
|
||||
border: 1px solid $fallback--border;
|
||||
border: 1px solid var(--border, $fallback--border);
|
||||
margin: 0.5em 0.8em 0.2em 0;
|
||||
}
|
||||
|
||||
i {
|
||||
position: absolute;
|
||||
margin: 10px;
|
||||
padding: 5px;
|
||||
background: rgba(230,230,230,0.6);
|
||||
border-radius: $fallback--attachmentRadius;
|
||||
border-radius: var(--attachmentRadius, $fallback--attachmentRadius);
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.btn {
|
||||
cursor: pointer;
|
||||
}
|
||||
.btn {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn[disabled] {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.btn[disabled] {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.icon-cancel {
|
||||
cursor: pointer;
|
||||
}
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0.6em;
|
||||
}
|
||||
.icon-cancel {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0.3em 0.5em 0.6em;
|
||||
line-height:24px;
|
||||
}
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0.6em;
|
||||
}
|
||||
|
||||
form textarea {
|
||||
border: solid;
|
||||
border-width: 1px;
|
||||
border-color: inherit;
|
||||
border-radius: 5px;
|
||||
line-height:16px;
|
||||
padding: 5px;
|
||||
resize: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0.3em 0.5em 0.6em;
|
||||
line-height:24px;
|
||||
}
|
||||
|
||||
form textarea:focus {
|
||||
min-height: 48px;
|
||||
}
|
||||
form textarea {
|
||||
line-height:16px;
|
||||
resize: none;
|
||||
overflow: hidden;
|
||||
transition: min-height 200ms 100ms;
|
||||
min-height: 1px;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.btn {
|
||||
cursor: pointer;
|
||||
}
|
||||
form textarea:focus {
|
||||
min-height: 48px;
|
||||
}
|
||||
|
||||
.btn[disabled] {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.btn {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icon-cancel {
|
||||
cursor: pointer;
|
||||
z-index: 4;
|
||||
}
|
||||
.btn[disabled] {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.autocomplete-panel {
|
||||
margin: 0 0.5em 0 0.5em;
|
||||
border-radius: 5px;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.5);
|
||||
min-width: 75%;
|
||||
}
|
||||
.icon-cancel {
|
||||
cursor: pointer;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.autocomplete {
|
||||
cursor: pointer;
|
||||
padding: 0.2em 0.4em 0.2em 0.4em;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.4);
|
||||
display: flex;
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 2px;
|
||||
object-fit: contain;
|
||||
}
|
||||
span {
|
||||
line-height: 24px;
|
||||
margin: 0 0.1em 0 0.2em;
|
||||
}
|
||||
small {
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
}
|
||||
.autocomplete-panel {
|
||||
margin: 0 0.5em 0 0.5em;
|
||||
border-radius: $fallback--tooltipRadius;
|
||||
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.5);
|
||||
min-width: 75%;
|
||||
background: $fallback--btn;
|
||||
background: var(--btn, $fallback--btn);
|
||||
color: $fallback--lightFg;
|
||||
color: var(--lightFg, $fallback--lightFg);
|
||||
}
|
||||
|
||||
.autocomplete {
|
||||
cursor: pointer;
|
||||
padding: 0.2em 0.4em 0.2em 0.4em;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.4);
|
||||
display: flex;
|
||||
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: $fallback--avatarRadius;
|
||||
border-radius: var(--avatarRadius, $fallback--avatarRadius);
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
span {
|
||||
line-height: 24px;
|
||||
margin: 0 0.1em 0 0.2em;
|
||||
}
|
||||
|
||||
small {
|
||||
margin-left: .5em;
|
||||
color: $fallback--faint;
|
||||
color: var(--faint, $fallback--faint);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="settings panel panel-default base00-background">
|
||||
<div class="panel-heading base02-background base04">
|
||||
<div class="settings panel panel-default">
|
||||
<div class="panel-heading">
|
||||
{{$t('registration.registration')}}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
@ -39,14 +39,14 @@
|
|||
</div>
|
||||
-->
|
||||
<div class='form-group'>
|
||||
<button :disabled="registering" type='submit' class='btn btn-default base05 base02-background'>{{$t('general.submit')}}</button>
|
||||
<button :disabled="registering" type='submit' class='btn btn-default'>{{$t('general.submit')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class='terms-of-service' v-html="termsofservice">
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="error" class='form-group'>
|
||||
<div class='error base05'>{{error}}</div>
|
||||
<div class='alert error'>{{error}}</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -55,6 +55,7 @@
|
|||
|
||||
<script src="./registration.js"></script>
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.registration-form {
|
||||
display: flex;
|
||||
|
@ -87,23 +88,10 @@
|
|||
}
|
||||
|
||||
form textarea {
|
||||
border: solid;
|
||||
border-width: 1px;
|
||||
border-color: silver;
|
||||
border-radius: 5px;
|
||||
line-height:16px;
|
||||
padding: 5px;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
input {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: silver;
|
||||
border-radius: 5px;
|
||||
padding: 0.1em 0.2em 0.2em 0.2em;
|
||||
}
|
||||
|
||||
.captcha {
|
||||
max-width: 350px;
|
||||
margin-bottom: 0.4em;
|
||||
|
@ -117,12 +105,7 @@
|
|||
}
|
||||
|
||||
.error {
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin: 0.5em 0.6em 0;
|
||||
background-color: rgba(255, 48, 16, 0.65);
|
||||
min-height: 28px;
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
<template>
|
||||
<div v-if="loggedIn">
|
||||
<i :class='classes' class='icon-retweet rt-active base09' v-on:click.prevent='retweet()'></i>
|
||||
<i :class='classes' class='icon-retweet rt-active' v-on:click.prevent='retweet()'></i>
|
||||
<span v-if='status.repeat_num > 0'>{{status.repeat_num}}</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<i :class='classes' class='icon-retweet base09'></i>
|
||||
<i :class='classes' class='icon-retweet'></i>
|
||||
<span v-if='status.repeat_num > 0'>{{status.repeat_num}}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./retweet_button.js" ></script>
|
||||
|
||||
<style lang='scss'>
|
||||
@import '../../_variables.scss';
|
||||
.rt-active {
|
||||
cursor: pointer;
|
||||
animation-duration: 0.6s;
|
||||
&:hover {
|
||||
color: $green;
|
||||
}
|
||||
}
|
||||
.icon-retweet.retweeted {
|
||||
color: $green;
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
.rt-active {
|
||||
cursor: pointer;
|
||||
animation-duration: 0.6s;
|
||||
&:hover {
|
||||
color: $fallback--cGreen;
|
||||
color: var(--cGreen, $fallback--cGreen);
|
||||
}
|
||||
}
|
||||
.icon-retweet.retweeted {
|
||||
color: $fallback--cGreen;
|
||||
color: var(--cGreen, $fallback--cGreen);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -10,7 +10,8 @@ const settings = {
|
|||
muteWordsString: this.$store.state.config.muteWords.join('\n'),
|
||||
autoLoadLocal: this.$store.state.config.autoLoad,
|
||||
streamingLocal: this.$store.state.config.streaming,
|
||||
hoverPreviewLocal: this.$store.state.config.hoverPreview
|
||||
hoverPreviewLocal: this.$store.state.config.hoverPreview,
|
||||
stopGifs: this.$store.state.config.stopGifs
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
@ -43,6 +44,9 @@ const settings = {
|
|||
muteWordsString (value) {
|
||||
value = filter(value.split('\n'), (word) => trim(word).length > 0)
|
||||
this.$store.dispatch('setOption', { name: 'muteWords', value })
|
||||
},
|
||||
stopGifs (value) {
|
||||
this.$store.dispatch('setOption', { name: 'stopGifs', value })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="settings panel panel-default base00-background">
|
||||
<div class="panel-heading base02-background base04">
|
||||
<div class="settings panel panel-default">
|
||||
<div class="panel-heading">
|
||||
{{$t('settings.settings')}}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
@ -29,8 +29,8 @@
|
|||
<label for="hideNsfw">{{$t('settings.nsfw_clickthrough')}}</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox" id="autoLoad" v-model="autoLoadLocal">
|
||||
<label for="autoLoad">{{$t('settings.autoload')}}</label>
|
||||
<input type="checkbox" id="autoload" v-model="autoLoadLocal">
|
||||
<label for="autoload">{{$t('settings.autoload')}}</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox" id="streaming" v-model="streamingLocal">
|
||||
|
@ -40,6 +40,10 @@
|
|||
<input type="checkbox" id="hoverPreview" v-model="hoverPreviewLocal">
|
||||
<label for="hoverPreview">{{$t('settings.reply_link_preview')}}</label>
|
||||
</li>
|
||||
<li>
|
||||
<input type="checkbox" id="stopGifs" v-model="stopGifs">
|
||||
<label for="stopGifs">{{$t('settings.stop_gifs')}}</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -50,32 +54,40 @@
|
|||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.setting-item {
|
||||
margin: 1em 1em 1.4em;
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
}
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.old-avatar {
|
||||
width: 128px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.setting-item {
|
||||
margin: 1em 1em 1.4em;
|
||||
|
||||
.new-avatar {
|
||||
object-fit: cover;
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
textarea {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-top: 1em;
|
||||
min-height: 28px;
|
||||
width: 10em;
|
||||
}
|
||||
}
|
||||
.setting-list {
|
||||
list-style-type: none;
|
||||
}
|
||||
.old-avatar {
|
||||
width: 128px;
|
||||
border-radius: $fallback--avatarRadius;
|
||||
border-radius: var(--avatarRadius, $fallback--avatarRadius);
|
||||
}
|
||||
|
||||
.new-avatar {
|
||||
object-fit: cover;
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
border-radius: $fallback--avatarRadius;
|
||||
border-radius: var(--avatarRadius, $fallback--avatarRadius);
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-top: 1em;
|
||||
min-height: 28px;
|
||||
width: 10em;
|
||||
}
|
||||
}
|
||||
.setting-list {
|
||||
list-style-type: none;
|
||||
li {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -4,9 +4,11 @@ import RetweetButton from '../retweet_button/retweet_button.vue'
|
|||
import DeleteButton from '../delete_button/delete_button.vue'
|
||||
import PostStatusForm from '../post_status_form/post_status_form.vue'
|
||||
import UserCardContent from '../user_card_content/user_card_content.vue'
|
||||
import StillImage from '../still-image/still-image.vue'
|
||||
import { filter, find } from 'lodash'
|
||||
|
||||
const Status = {
|
||||
name: 'Status',
|
||||
props: [
|
||||
'statusoid',
|
||||
'expandable',
|
||||
|
@ -14,7 +16,10 @@ const Status = {
|
|||
'focused',
|
||||
'highlight',
|
||||
'compact',
|
||||
'replies'
|
||||
'replies',
|
||||
'noReplyLinks',
|
||||
'noHeading',
|
||||
'inlineExpanded'
|
||||
],
|
||||
data: () => ({
|
||||
replying: false,
|
||||
|
@ -22,7 +27,8 @@ const Status = {
|
|||
unmuted: false,
|
||||
userExpanded: false,
|
||||
preview: null,
|
||||
showPreview: false
|
||||
showPreview: false,
|
||||
showingTall: false
|
||||
}),
|
||||
computed: {
|
||||
muteWords () {
|
||||
|
@ -54,11 +60,6 @@ const Status = {
|
|||
},
|
||||
muted () { return !this.unmuted && (this.status.user.muted || this.muteWordHits.length > 0) },
|
||||
isReply () { return !!this.status.in_reply_to_status_id },
|
||||
borderColor () {
|
||||
return {
|
||||
borderBottomColor: this.$store.state.config.colors['base02']
|
||||
}
|
||||
},
|
||||
isFocused () {
|
||||
// retweet or root of an expanded conversation
|
||||
if (this.focused) {
|
||||
|
@ -68,6 +69,29 @@ const Status = {
|
|||
}
|
||||
// use conversation highlight only when in conversation
|
||||
return this.status.id === this.highlight
|
||||
},
|
||||
// This is a bit hacky, but we want to approximate post height before rendering
|
||||
// so we count newlines (masto uses <p> for paragraphs, GS uses <br> between them)
|
||||
// as well as approximate line count by counting characters and approximating ~80
|
||||
// per line.
|
||||
//
|
||||
// Using max-height + overflow: auto for status components resulted in false positives
|
||||
// very often with japanese characters, and it was very annoying.
|
||||
hideTallStatus () {
|
||||
if (this.showingTall) {
|
||||
return false
|
||||
}
|
||||
const lengthScore = this.status.statusnet_html.split(/<p|<br/).length + this.status.text.length / 80
|
||||
return lengthScore > 20
|
||||
},
|
||||
attachmentSize () {
|
||||
if ((this.$store.state.config.hideAttachments && !this.inConversation) ||
|
||||
(this.$store.state.config.hideAttachmentsInConv && this.inConversation)) {
|
||||
return 'hide'
|
||||
} else if (this.compact) {
|
||||
return 'small'
|
||||
}
|
||||
return 'normal'
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
@ -76,7 +100,8 @@ const Status = {
|
|||
RetweetButton,
|
||||
DeleteButton,
|
||||
PostStatusForm,
|
||||
UserCardContent
|
||||
UserCardContent,
|
||||
StillImage
|
||||
},
|
||||
methods: {
|
||||
linkClicked ({target}) {
|
||||
|
@ -105,6 +130,9 @@ const Status = {
|
|||
toggleUserExpanded () {
|
||||
this.userExpanded = !this.userExpanded
|
||||
},
|
||||
toggleShowTall () {
|
||||
this.showingTall = !this.showingTall
|
||||
},
|
||||
replyEnter (id, event) {
|
||||
this.showPreview = true
|
||||
const targetId = Number(id)
|
||||
|
|
|
@ -1,123 +1,99 @@
|
|||
<template>
|
||||
<div class="status-el base00-background" v-if="compact">
|
||||
<div @click.prevent="linkClicked" class="status-content" v-html="status.statusnet_html"></div>
|
||||
<div v-if="loggedIn">
|
||||
<div class='status-actions'>
|
||||
<div>
|
||||
<a href="#" v-on:click.prevent="toggleReplying">
|
||||
<i class="base09 icon-reply" :class="{'icon-reply-active': replying}"></i>
|
||||
</a>
|
||||
</div>
|
||||
<retweet-button :loggedIn="loggedIn" :status=status></retweet-button>
|
||||
<favorite-button :loggedIn="loggedIn" :status=status></favorite-button>
|
||||
</div>
|
||||
</div>
|
||||
<post-status-form class="reply-body" :reply-to="status.id" :attentions="status.attentions" :repliedUser="status.user" v-on:posted="toggleReplying" v-if="replying"/>
|
||||
</div>
|
||||
<div class="status-el base00-background base03-border status-fadein" v-else-if="!status.deleted" v-bind:class="[{ 'base01-background': isFocused }, { 'status-conversation': inConversation }]" >
|
||||
<template v-if="muted">
|
||||
<div class="status-el" :class="[{ 'status-el_focused': isFocused }, { 'status-conversation': inlineExpanded }]">
|
||||
<template v-if="muted && !noReplyLinks">
|
||||
<div class="media status container muted">
|
||||
<small><router-link :to="{ name: 'user-profile', params: { id: status.user.id } }">{{status.user.screen_name}}</router-link></small>
|
||||
<small class="muteWords">{{muteWordHits.join(', ')}}</small>
|
||||
<a href="#" class="unmute" @click.prevent="toggleMute"><i class="base09 icon-eye-off"></i></a>
|
||||
<a href="#" class="unmute" @click.prevent="toggleMute"><i class="icon-eye-off"></i></a>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="!muted">
|
||||
<div v-if="retweet" class="media container retweet-info">
|
||||
<div class="media-left">
|
||||
<template v-else>
|
||||
<div v-if="retweet && !noHeading" class="media container retweet-info">
|
||||
<StillImage v-if="retweet" class='avatar' :src="statusoid.user.profile_image_url_original"/>
|
||||
<div class="media-body faint">
|
||||
<a :href="statusoid.user.statusnet_profile_url" style="font-weight: bold;" :title="'@'+statusoid.user.screen_name">{{retweeter}}</a>
|
||||
<i class='fa icon-retweet retweeted'></i>
|
||||
</div>
|
||||
<div class="media-body">
|
||||
Repeated by <a :href="statusoid.user.statusnet_profile_url" style="font-weight: bold;" :title="'@'+statusoid.user.screen_name">{{retweeter}}</a>
|
||||
{{$t('timeline.repeated')}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="media status container">
|
||||
<div class="media-left">
|
||||
<a :href="status.user.statusnet_profile_url">
|
||||
<img @click.prevent="toggleUserExpanded" :class="{retweeted: retweet}" class='avatar' :src="status.user.profile_image_url_original">
|
||||
<img v-if="retweet" class='avatar-retweeter' :src="statusoid.user.profile_image_url_original"></img>
|
||||
|
||||
<div class="media status">
|
||||
<div v-if="!noHeading" class="media-left">
|
||||
<a :href="status.user.statusnet_profile_url" @click.stop.prevent.capture="toggleUserExpanded">
|
||||
<StillImage class='avatar' :class="{'avatar-compact': compact}" :src="status.user.profile_image_url_original"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="media-body">
|
||||
<div class="base03-border usercard" v-if="userExpanded">
|
||||
<div class="status-body">
|
||||
<div class="usercard media-body" v-if="userExpanded">
|
||||
<user-card-content :user="status.user" :switcher="false"></user-card-content>
|
||||
</div>
|
||||
<div class="user-content">
|
||||
<div class="media-heading">
|
||||
<div v-if="!noHeading" class="media-body container media-heading">
|
||||
<div class="media-heading-left">
|
||||
<div class="name-and-links">
|
||||
<h4 class="user-name">{{status.user.name}}</h4>
|
||||
<div class="links">
|
||||
<h4>
|
||||
<small><router-link :to="{ name: 'user-profile', params: { id: status.user.id } }">{{status.user.screen_name}}</router-link></small>
|
||||
<small v-if="status.in_reply_to_screen_name"> >
|
||||
<span class="links">
|
||||
<router-link :to="{ name: 'user-profile', params: { id: status.user.id } }">{{status.user.screen_name}}</router-link>
|
||||
<span v-if="status.in_reply_to_screen_name" class="faint reply-info">
|
||||
<i class="icon-right-open"></i>
|
||||
<router-link :to="{ name: 'user-profile', params: { id: status.in_reply_to_user_id } }">
|
||||
{{status.in_reply_to_screen_name}}
|
||||
</router-link>
|
||||
</small>
|
||||
<template v-if="isReply">
|
||||
<small>
|
||||
<a href="#" @click.prevent="gotoOriginal(status.in_reply_to_status_id)"><i class="icon-reply" @mouseenter="replyEnter(status.in_reply_to_status_id, $event)" @mouseout="replyLeave()"></i></a>
|
||||
</small>
|
||||
</template>
|
||||
-
|
||||
<small>
|
||||
<router-link :to="{ name: 'conversation', params: { id: status.id } }">
|
||||
<timeago :since="status.created_at" :auto-update="60"></timeago>
|
||||
</router-link>
|
||||
</small>
|
||||
</h4>
|
||||
</div>
|
||||
<h4 class="replies" v-if="inConversation">
|
||||
<small v-if="replies.length">Replies:</small>
|
||||
<small v-for="reply in replies">
|
||||
<a href="#" @click.prevent="gotoOriginal(reply.id)" @mouseenter="replyEnter(reply.id, $event)" @mouseout="replyLeave()">{{reply.name}} </a>
|
||||
</small>
|
||||
</h4>
|
||||
</div>
|
||||
<div class="heading-icons">
|
||||
<a href="#" @click.prevent="toggleMute" v-if="unmuted"><i class="base09 icon-eye-off"></i></a>
|
||||
<a :href="status.external_url" target="_blank" v-if="!status.is_local" class="source_url"><i class="base09 icon-binoculars"></i></a>
|
||||
<template v-if="expandable">
|
||||
<a href="#" @click.prevent="toggleExpanded" class="expand"><i class="base09 icon-plus-squared"></i></a>
|
||||
</template>
|
||||
</span>
|
||||
<a v-if="isReply && !noReplyLinks" href="#" @click.prevent="gotoOriginal(status.in_reply_to_status_id)">
|
||||
<i class="icon-reply" @mouseenter="replyEnter(status.in_reply_to_status_id, $event)" @mouseout="replyLeave()"></i>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<h4 class="replies" v-if="inConversation && !noReplyLinks">
|
||||
<small v-if="replies.length">Replies:</small>
|
||||
<small class="reply-link" v-for="reply in replies">
|
||||
<a href="#" @click.prevent="gotoOriginal(reply.id)" @mouseenter="replyEnter(reply.id, $event)" @mouseout="replyLeave()">{{reply.name}} </a>
|
||||
</small>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="status-preview base00-background base03-border" v-if="showPreview && preview">
|
||||
<img class="avatar" :src="preview.user.profile_image_url_original">
|
||||
<div class="text">
|
||||
<h4>
|
||||
{{ preview.user.name }}
|
||||
<small><a>{{ preview.user.screen_name}}</a></small>
|
||||
</h4>
|
||||
<div @click.prevent="linkClicked" class="status-content" v-html="preview.statusnet_html"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="status-preview status-preview-loading base00-background base03-border" v-else-if="showPreview">
|
||||
<i class="base09 icon-spin4 animate-spin"></i>
|
||||
</div>
|
||||
|
||||
<div @click.prevent="linkClicked" class="status-content" v-html="status.statusnet_html"></div>
|
||||
|
||||
<div v-if='status.attachments' class='attachments'>
|
||||
<attachment v-if="!hideAttachments" :status-id="status.id" :nsfw="status.nsfw" :attachment="attachment" v-for="attachment in status.attachments" :key="attachment.id">
|
||||
</attachment>
|
||||
<div class="media-heading-right">
|
||||
<router-link class="timeago" :to="{ name: 'conversation', params: { id: status.id } }">
|
||||
<timeago :since="status.created_at" :auto-update="60"></timeago>
|
||||
</router-link>
|
||||
<a :href="status.external_url" target="_blank" v-if="!status.is_local" class="source_url"><i class="icon-link-ext"></i></a>
|
||||
<template v-if="expandable">
|
||||
<a href="#" @click.prevent="toggleExpanded"><i class="icon-plus-squared"></i></a>
|
||||
</template>
|
||||
<a href="#" @click.prevent="toggleMute" v-if="unmuted"><i class="icon-eye-off"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='status-actions'>
|
||||
<div v-if="showPreview" class="status-preview-container">
|
||||
<status class="status-preview" v-if="preview" :noReplyLinks="true" :statusoid="preview" :compact=true></status>
|
||||
<div class="status-preview status-preview-loading" v-else>
|
||||
<i class="icon-spin4 animate-spin"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div :class="{'tall-status': hideTallStatus}" class="status-content-wrapper">
|
||||
<a class="tall-status-hider" :class="{ 'tall-status-hider_focused': isFocused }" v-if="hideTallStatus" href="#" @click.prevent="toggleShowTall">Show more</a>
|
||||
<div @click.prevent="linkClicked" class="status-content media-body" v-html="status.statusnet_html"></div>
|
||||
<a v-if="showingTall" href="#" class="tall-status-unhider" @click.prevent="toggleShowTall">Show less</a>
|
||||
</div>
|
||||
|
||||
<div v-if='status.attachments' class='attachments media-body'>
|
||||
<attachment :size="attachmentSize" :status-id="status.id" :nsfw="status.nsfw" :attachment="attachment" v-for="attachment in status.attachments" :key="attachment.id">
|
||||
</attachment>
|
||||
</div>
|
||||
|
||||
<div v-if="!noHeading && !noReplyLinks" class='status-actions media-body'>
|
||||
<div v-if="loggedIn">
|
||||
<a href="#" v-on:click.prevent="toggleReplying">
|
||||
<i class="base09 icon-reply" :class="{'icon-reply-active': replying}"></i>
|
||||
<i class="icon-reply" :class="{'icon-reply-active': replying}"></i>
|
||||
</a>
|
||||
</div>
|
||||
<retweet-button :loggedIn="loggedIn" :status=status></retweet-button>
|
||||
<favorite-button :loggedIn="loggedIn" :status=status></favorite-button>
|
||||
<delete-button :status=status></delete-button>
|
||||
<retweet-button :loggedIn='loggedIn' :status='status'></retweet-button>
|
||||
<favorite-button :loggedIn='loggedIn' :status='status'></favorite-button>
|
||||
<delete-button :status='status'></delete-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="status base00-background container" v-if="replying">
|
||||
<div class="container" v-if="replying">
|
||||
<div class="reply-left"/>
|
||||
<post-status-form class="reply-body" :reply-to="status.id" :attentions="status.attentions" :repliedUser="status.user" v-on:posted="toggleReplying"/>
|
||||
</div>
|
||||
|
@ -126,300 +102,387 @@
|
|||
</template>
|
||||
|
||||
<script src="./status.js" ></script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
@import '../../_variables.scss';
|
||||
|
||||
status-text-container {
|
||||
display: block;
|
||||
.status-body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.status-preview.status-el {
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: $fallback--border;
|
||||
border-color: var(--border, $fallback--border);
|
||||
}
|
||||
|
||||
.status-preview-container {
|
||||
position: relative;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.status-preview {
|
||||
position: absolute;
|
||||
max-width: 95%;
|
||||
display: flex;
|
||||
background-color: $fallback--bg;
|
||||
background-color: var(--bg, $fallback--bg);
|
||||
border-color: $fallback--border;
|
||||
border-color: var(--border, $fallback--border);
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: $fallback--tooltipRadius;
|
||||
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
|
||||
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
|
||||
margin-top: 0.25em;
|
||||
margin-left: 0.5em;
|
||||
z-index: 50;
|
||||
.status {
|
||||
flex: 1;
|
||||
border: 0;
|
||||
min-width: 15em;
|
||||
}
|
||||
}
|
||||
|
||||
.status-preview {
|
||||
position: absolute;
|
||||
max-width: 34em;
|
||||
padding: 0.5em;
|
||||
display: flex;
|
||||
border-color: inherit;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
|
||||
margin-top: 0.5em;
|
||||
margin-left: 1em;
|
||||
|
||||
.avatar {
|
||||
flex-shrink: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.text {
|
||||
h4 {
|
||||
margin-bottom: 0.4em;
|
||||
small {
|
||||
font-weight: lighter;
|
||||
}
|
||||
}
|
||||
padding: 0 0.5em 0.5em 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.status-preview-loading {
|
||||
display: block;
|
||||
.status-preview-loading {
|
||||
display: block;
|
||||
min-width: 15em;
|
||||
padding: 1em;
|
||||
text-align: center;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
i {
|
||||
font-size: 2em;
|
||||
min-width: 8em;
|
||||
}
|
||||
}
|
||||
|
||||
.status-el {
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
border-left-width: 0px;
|
||||
line-height: 18px;
|
||||
min-width: 0;
|
||||
background-color: $fallback--bg;
|
||||
background-color: var(--bg, $fallback--bg);
|
||||
border-color: $fallback--border;
|
||||
border-color: var(--border, $fallback--border);
|
||||
|
||||
border-left: 4px $fallback--cRed;
|
||||
border-left: 4px var(--cRed, $fallback--cRed);
|
||||
|
||||
&_focused {
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--lightBg, $fallback--lightBg);
|
||||
}
|
||||
|
||||
.timeline & {
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
|
||||
.media-body {
|
||||
flex: 1;
|
||||
padding: 0;
|
||||
margin: 0 0 0.25em 0.8em;
|
||||
}
|
||||
|
||||
.media-heading {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.media-heading-left {
|
||||
padding: 0;
|
||||
vertical-align: bottom;
|
||||
flex-basis: 100%;
|
||||
|
||||
small {
|
||||
font-weight: lighter;
|
||||
}
|
||||
h4 {
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
margin-right: 0.25em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.name-and-links {
|
||||
padding: 0;
|
||||
flex: 1 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-content: center;
|
||||
}
|
||||
.links {
|
||||
display: flex;
|
||||
padding-top: 1px;
|
||||
margin-left: 0.2em;
|
||||
font-size: 12px;
|
||||
color: $fallback--link;
|
||||
color: var(--link, $fallback--link);
|
||||
max-width: 100%;
|
||||
a {
|
||||
max-width: 100%;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.reply-info {
|
||||
display: flex;
|
||||
}
|
||||
.replies {
|
||||
line-height: 16px;
|
||||
}
|
||||
.reply-link {
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
}
|
||||
|
||||
.media-heading-right {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
max-height: 1.5em;
|
||||
margin-left: 0.25em;
|
||||
.timeago {
|
||||
margin-right: 0.2em;
|
||||
font-size: 12px;
|
||||
padding-top: 1px;
|
||||
}
|
||||
i {
|
||||
margin-left: 0.2em;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
display: inline-block;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.tall-status {
|
||||
position: relative;
|
||||
height: 220px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.tall-status-hider {
|
||||
position: absolute;
|
||||
height: 70px;
|
||||
margin-top: 150px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
line-height: 110px;
|
||||
background: linear-gradient(to bottom, rgba(0, 0, 0, 0), $fallback--bg 80%);
|
||||
background: linear-gradient(to bottom, rgba(0, 0, 0, 0), var(--bg, $fallback--bg) 80%);
|
||||
&_focused {
|
||||
background: linear-gradient(to bottom, rgba(0, 0, 0, 0), $fallback--lightBg 80%);
|
||||
background: linear-gradient(to bottom, rgba(0, 0, 0, 0), var(--lightBg, $fallback--lightBg) 80%);
|
||||
}
|
||||
}
|
||||
|
||||
.tall-status-unhider {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.status-el {
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
border-left-width: 0px;
|
||||
line-height: 18px;
|
||||
.status-content {
|
||||
margin-right: 0.5em;
|
||||
img, video {
|
||||
max-width: 100%;
|
||||
max-height: 400px;
|
||||
vertical-align: middle;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.timeline & {
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
blockquote {
|
||||
margin: 0.2em 0 0.2em 2em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.notify {
|
||||
.avatar {
|
||||
border-width: 3px;
|
||||
border-style: solid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
margin-top: 0.2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.media-body {
|
||||
flex: 1;
|
||||
padding-left: 0.5em;
|
||||
}
|
||||
.retweet-info {
|
||||
padding: 0.4em 0.6em 0 0.6em;
|
||||
margin: 0 0 -0.5em 0;
|
||||
.avatar {
|
||||
border-radius: $fallback--avatarAltRadius;
|
||||
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
|
||||
margin-left: 28px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.media-body {
|
||||
font-size: 1em;
|
||||
line-height: 22px;
|
||||
|
||||
.user-content {
|
||||
display: flex;
|
||||
align-content: center;
|
||||
flex-wrap: wrap;
|
||||
i {
|
||||
padding: 0 0.2em;
|
||||
}
|
||||
a {
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
min-height: 52px;
|
||||
padding-top: 1px;
|
||||
}
|
||||
.status-fadein {
|
||||
animation-duration: 0.4s;
|
||||
animation-name: fadein;
|
||||
}
|
||||
|
||||
.media-heading {
|
||||
display: flex;
|
||||
min-height: 1.4em;
|
||||
margin-bottom: 0.3em;
|
||||
@keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
small {
|
||||
font-weight: lighter;
|
||||
}
|
||||
h4 {
|
||||
margin-right: 0.4em;
|
||||
}
|
||||
.name-and-links {
|
||||
flex: 1 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.replies {
|
||||
flex-basis: 100%;
|
||||
}
|
||||
}
|
||||
.greentext {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.source_url {
|
||||
.status-conversation {
|
||||
border-left-style: solid;
|
||||
}
|
||||
|
||||
}
|
||||
.status-actions {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
.expand {
|
||||
margin-right: -0.3em;
|
||||
}
|
||||
div, favorite-button {
|
||||
padding-top: 0.25em;
|
||||
max-width: 6em;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
display: inline-block;
|
||||
word-break: break-all;
|
||||
}
|
||||
.icon-reply:hover {
|
||||
color: $fallback--cBlue;
|
||||
color: var(--cBlue, $fallback--cBlue);
|
||||
}
|
||||
|
||||
.status-content {
|
||||
margin: 3px 15px 4px 0;
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
.icon-reply.icon-reply-active {
|
||||
color: $fallback--cBlue;
|
||||
color: var(--cBlue, $fallback--cBlue);
|
||||
}
|
||||
|
||||
img, video {
|
||||
max-width: 100%;
|
||||
max-height: 400px;
|
||||
vertical-align: middle;
|
||||
object-fit: contain;
|
||||
}
|
||||
.status .avatar-compact {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: $fallback--avatarAltRadius;
|
||||
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0.2em 0 0.2em 2em;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
.avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: $fallback--avatarRadius;
|
||||
border-radius: var(--avatarRadius, $fallback--avatarRadius);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
margin-top: 0.2em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.media-left {
|
||||
margin: 0.2em 0.3em 0 0;
|
||||
img {
|
||||
float: right;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
&.animated::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.retweet-info {
|
||||
padding: 0.7em 0 0 0.6em;
|
||||
&.retweeted {
|
||||
}
|
||||
}
|
||||
|
||||
.media-left {
|
||||
display: flex;
|
||||
.status:hover .animated.avatar {
|
||||
canvas {
|
||||
display: none;
|
||||
}
|
||||
img {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
align-self: center;
|
||||
text-align: right;
|
||||
flex: 1;
|
||||
padding-right: 0.3em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.status {
|
||||
display: flex;
|
||||
padding: 0.6em;
|
||||
}
|
||||
|
||||
.status-fadein {
|
||||
animation-duration: 0.5s;
|
||||
animation-name: fadein;
|
||||
}
|
||||
.status-conversation:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.muted {
|
||||
padding: 0.25em 0.5em;
|
||||
button {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.greentext {
|
||||
color: green;
|
||||
}
|
||||
.muteWords {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.status-conversation {
|
||||
border-left-style: solid;
|
||||
}
|
||||
a.unmute {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.status-actions {
|
||||
padding-top: 0.15em;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
.reply-left {
|
||||
flex: 0;
|
||||
min-width: 48px;
|
||||
}
|
||||
|
||||
div, favorite-button {
|
||||
max-width: 6em;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
.reply-body {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.icon-reply:hover {
|
||||
color: $blue;
|
||||
}
|
||||
.timeline > {
|
||||
.status-el:last-child {
|
||||
border-bottom-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;;
|
||||
border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
|
||||
}
|
||||
}
|
||||
|
||||
.icon-reply.icon-reply-active {
|
||||
color: $blue;
|
||||
}
|
||||
@media all and (max-width: 960px) {
|
||||
.status-el {
|
||||
.retweet-info {
|
||||
.avatar {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.status {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.status .avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
.status .avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
&.retweeted {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-right: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.status img.avatar-retweeter {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
position: absolute;
|
||||
margin-left: 24px;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.status.compact .avatar {
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.status {
|
||||
padding: 0.4em 0.7em 0.45em 0.7em;
|
||||
border-left: 4px rgba(255, 48, 16, 0.65);
|
||||
border-left-style: inherit;
|
||||
}
|
||||
|
||||
.status-conversation:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.timeline .panel.timeline {
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.muted {
|
||||
padding: 0.1em 0.4em 0.1em 0.8em;
|
||||
button {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.muteWords {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
a.unmute {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.reply-left {
|
||||
flex: 0;
|
||||
min-width: 48px;
|
||||
}
|
||||
|
||||
.reply-body {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
@media all and (max-width: 960px) {
|
||||
.status-el {
|
||||
.name-and-links {
|
||||
margin-left: -0.25em;
|
||||
}
|
||||
}
|
||||
.status {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.status .avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
&.retweeted {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
margin-right: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.status img.avatar-retweeter {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
position: absolute;
|
||||
margin-left: 18px;
|
||||
margin-top: 18px;
|
||||
}
|
||||
}
|
||||
.status .avatar-compact {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
26
src/components/still-image/still-image.js
Normal file
26
src/components/still-image/still-image.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
const StillImage = {
|
||||
props: [
|
||||
'src',
|
||||
'referrerpolicy',
|
||||
'mimetype'
|
||||
],
|
||||
data () {
|
||||
return {
|
||||
stopGifs: this.$store.state.config.stopGifs
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
animated () {
|
||||
return this.stopGifs && (this.mimetype === 'image/gif' || this.src.endsWith('.gif'))
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onLoad () {
|
||||
const canvas = this.$refs.canvas
|
||||
if (!canvas) return
|
||||
canvas.getContext('2d').drawImage(this.$refs.src, 1, 1, canvas.width, canvas.height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default StillImage
|
65
src/components/still-image/still-image.vue
Normal file
65
src/components/still-image/still-image.vue
Normal file
|
@ -0,0 +1,65 @@
|
|||
<template>
|
||||
<div class='still-image' :class='{ animated: animated }' >
|
||||
<canvas ref="canvas" v-if="animated"></canvas>
|
||||
<img ref="src" :src="src" :referrerpolicy="referrerpolicy" v-on:load="onLoad"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./still-image.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
.still-image {
|
||||
position: relative;
|
||||
line-height: 0;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
&:hover canvas {
|
||||
display: none;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.animated {
|
||||
&:hover::before,
|
||||
img {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
&:hover img {
|
||||
visibility: visible
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: 'gif';
|
||||
position: absolute;
|
||||
line-height: 10px;
|
||||
font-size: 10px;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
background: rgba(127,127,127,.5);
|
||||
color: #FFF;
|
||||
display: block;
|
||||
padding: 2px 4px;
|
||||
border-radius: $fallback--tooltipRadius;
|
||||
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
||||
canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -6,9 +6,19 @@ export default {
|
|||
availableStyles: [],
|
||||
selected: this.$store.state.config.theme,
|
||||
bgColorLocal: '',
|
||||
fgColorLocal: '',
|
||||
btnColorLocal: '',
|
||||
textColorLocal: '',
|
||||
linkColorLocal: ''
|
||||
linkColorLocal: '',
|
||||
redColorLocal: '',
|
||||
blueColorLocal: '',
|
||||
greenColorLocal: '',
|
||||
orangeColorLocal: '',
|
||||
btnRadiusLocal: '',
|
||||
panelRadiusLocal: '',
|
||||
avatarRadiusLocal: '',
|
||||
avatarAltRadiusLocal: '',
|
||||
attachmentRadiusLocal: '',
|
||||
tooltipRadiusLocal: ''
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
@ -21,16 +31,29 @@ export default {
|
|||
})
|
||||
},
|
||||
mounted () {
|
||||
this.bgColorLocal = rgbstr2hex(this.$store.state.config.colors['base00'])
|
||||
this.fgColorLocal = rgbstr2hex(this.$store.state.config.colors['base02'])
|
||||
this.textColorLocal = rgbstr2hex(this.$store.state.config.colors['base05'])
|
||||
this.linkColorLocal = rgbstr2hex(this.$store.state.config.colors['base08'])
|
||||
this.bgColorLocal = rgbstr2hex(this.$store.state.config.colors.bg)
|
||||
this.btnColorLocal = rgbstr2hex(this.$store.state.config.colors.btn)
|
||||
this.textColorLocal = rgbstr2hex(this.$store.state.config.colors.fg)
|
||||
this.linkColorLocal = rgbstr2hex(this.$store.state.config.colors.link)
|
||||
|
||||
this.redColorLocal = rgbstr2hex(this.$store.state.config.colors.cRed)
|
||||
this.blueColorLocal = rgbstr2hex(this.$store.state.config.colors.cBlue)
|
||||
this.greenColorLocal = rgbstr2hex(this.$store.state.config.colors.cGreen)
|
||||
this.orangeColorLocal = rgbstr2hex(this.$store.state.config.colors.cOrange)
|
||||
|
||||
this.btnRadiusLocal = this.$store.state.config.radii.btnRadius || 4
|
||||
this.panelRadiusLocal = this.$store.state.config.radii.panelRadius || 10
|
||||
this.avatarRadiusLocal = this.$store.state.config.radii.avatarRadius || 5
|
||||
this.avatarAltRadiusLocal = this.$store.state.config.radii.avatarAltRadius || 50
|
||||
this.tooltipRadiusLocal = this.$store.state.config.radii.tooltipRadius || 2
|
||||
this.attachmentRadiusLocal = this.$store.state.config.radii.attachmentRadius || 5
|
||||
},
|
||||
methods: {
|
||||
setCustomTheme () {
|
||||
if (!this.bgColorLocal && !this.fgColorLocal && !this.linkColorLocal) {
|
||||
if (!this.bgColorLocal && !this.btnColorLocal && !this.linkColorLocal) {
|
||||
// reset to picked themes
|
||||
}
|
||||
|
||||
const rgb = (hex) => {
|
||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
|
||||
return result ? {
|
||||
|
@ -40,17 +63,33 @@ export default {
|
|||
} : null
|
||||
}
|
||||
const bgRgb = rgb(this.bgColorLocal)
|
||||
const fgRgb = rgb(this.fgColorLocal)
|
||||
const btnRgb = rgb(this.btnColorLocal)
|
||||
const textRgb = rgb(this.textColorLocal)
|
||||
const linkRgb = rgb(this.linkColorLocal)
|
||||
if (bgRgb && fgRgb && linkRgb) {
|
||||
|
||||
const redRgb = rgb(this.redColorLocal)
|
||||
const blueRgb = rgb(this.blueColorLocal)
|
||||
const greenRgb = rgb(this.greenColorLocal)
|
||||
const orangeRgb = rgb(this.orangeColorLocal)
|
||||
|
||||
if (bgRgb && btnRgb && linkRgb) {
|
||||
this.$store.dispatch('setOption', {
|
||||
name: 'customTheme',
|
||||
value: {
|
||||
fg: fgRgb,
|
||||
fg: btnRgb,
|
||||
bg: bgRgb,
|
||||
text: textRgb,
|
||||
link: linkRgb
|
||||
link: linkRgb,
|
||||
cRed: redRgb,
|
||||
cBlue: blueRgb,
|
||||
cGreen: greenRgb,
|
||||
cOrange: orangeRgb,
|
||||
btnRadius: this.btnRadiusLocal,
|
||||
panelRadius: this.panelRadiusLocal,
|
||||
avatarRadius: this.avatarRadiusLocal,
|
||||
avatarAltRadius: this.avatarAltRadiusLocal,
|
||||
tooltipRadius: this.tooltipRadiusLocal,
|
||||
attachmentRadius: this.attachmentRadiusLocal
|
||||
}})
|
||||
}
|
||||
}
|
||||
|
@ -58,9 +97,13 @@ export default {
|
|||
watch: {
|
||||
selected () {
|
||||
this.bgColorLocal = this.selected[1]
|
||||
this.fgColorLocal = this.selected[2]
|
||||
this.btnColorLocal = this.selected[2]
|
||||
this.textColorLocal = this.selected[3]
|
||||
this.linkColorLocal = this.selected[4]
|
||||
this.redColorLocal = this.selected[5]
|
||||
this.greenColorLocal = this.selected[6]
|
||||
this.blueColorLocal = this.selected[7]
|
||||
this.orangeColorLocal = this.selected[8]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,99 +1,231 @@
|
|||
<template>
|
||||
<div>
|
||||
<p>{{$t('settings.presets')}}</p>
|
||||
<select v-model="selected" class="style-switcher">
|
||||
<option v-for="style in availableStyles" :value="style">{{style[0]}}</option>
|
||||
</select>
|
||||
<p>{{$t('settings.theme_help')}}</p>
|
||||
<div>{{$t('settings.presets')}}
|
||||
<label for="style-switcher" class='select'>
|
||||
<select id="style-switcher" v-model="selected" class="style-switcher">
|
||||
<option v-for="style in availableStyles" :value="style">{{style[0]}}</option>
|
||||
</select>
|
||||
<i class="icon-down-open"/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="color-container">
|
||||
<p>{{$t('settings.theme_help')}}</p>
|
||||
<div class="color-item">
|
||||
<label for="bgcolor" class="base04 theme-color-lb">{{$t('settings.background')}}</label>
|
||||
<label for="bgcolor" class="theme-color-lb">{{$t('settings.background')}}</label>
|
||||
<input id="bgcolor" class="theme-color-cl" type="color" v-model="bgColorLocal">
|
||||
<input id="bgcolor-t" class="theme-color-in" type="text" v-model="bgColorLocal">
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<label for="fgcolor" class="base04 theme-color-lb">{{$t('settings.foreground')}}</label>
|
||||
<input id="fgcolor" class="theme-color-cl" type="color" v-model="fgColorLocal">
|
||||
<input id="fgcolor-t" class="theme-color-in" type="text" v-model="fgColorLocal">
|
||||
<label for="fgcolor" class="theme-color-lb">{{$t('settings.foreground')}}</label>
|
||||
<input id="fgcolor" class="theme-color-cl" type="color" v-model="btnColorLocal">
|
||||
<input id="fgcolor-t" class="theme-color-in" type="text" v-model="btnColorLocal">
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<label for="textcolor" class="base04 theme-color-lb">{{$t('settings.text')}}</label>
|
||||
<label for="textcolor" class="theme-color-lb">{{$t('settings.text')}}</label>
|
||||
<input id="textcolor" class="theme-color-cl" type="color" v-model="textColorLocal">
|
||||
<input id="textcolor-t" class="theme-color-in" type="text" v-model="textColorLocal">
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<label for="linkcolor" class="base04 theme-color-lb">{{$t('settings.links')}}</label>
|
||||
<label for="linkcolor" class="theme-color-lb">{{$t('settings.links')}}</label>
|
||||
<input id="linkcolor" class="theme-color-cl" type="color" v-model="linkColorLocal">
|
||||
<input id="linkcolor-t" class="theme-color-in" type="text" v-model="linkColorLocal">
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<label for="redcolor" class="theme-color-lb">{{$t('settings.cRed')}}</label>
|
||||
<input id="redcolor" class="theme-color-cl" type="color" v-model="redColorLocal">
|
||||
<input id="redcolor-t" class="theme-color-in" type="text" v-model="redColorLocal">
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<label for="bluecolor" class="theme-color-lb">{{$t('settings.cBlue')}}</label>
|
||||
<input id="bluecolor" class="theme-color-cl" type="color" v-model="blueColorLocal">
|
||||
<input id="bluecolor-t" class="theme-color-in" type="text" v-model="blueColorLocal">
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<label for="greencolor" class="theme-color-lb">{{$t('settings.cGreen')}}</label>
|
||||
<input id="greencolor" class="theme-color-cl" type="color" v-model="greenColorLocal">
|
||||
<input id="greencolor-t" class="theme-color-in" type="green" v-model="greenColorLocal">
|
||||
</div>
|
||||
<div class="color-item">
|
||||
<label for="orangecolor" class="theme-color-lb">{{$t('settings.cOrange')}}</label>
|
||||
<input id="orangecolor" class="theme-color-cl" type="color" v-model="orangeColorLocal">
|
||||
<input id="orangecolor-t" class="theme-color-in" type="text" v-model="orangeColorLocal">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="panel">
|
||||
<div class="panel-heading" :style="{ 'background-color': fgColorLocal, 'color': textColorLocal }">Preview</div>
|
||||
<div class="radius-container">
|
||||
<p>{{$t('settings.radii_help')}}</p>
|
||||
<div class="radius-item">
|
||||
<label for="btnradius" class="theme-radius-lb">{{$t('settings.btnRadius')}}</label>
|
||||
<input id="btnradius" class="theme-radius-rn" type="range" v-model="btnRadiusLocal" max="16">
|
||||
<input id="btnradius-t" class="theme-radius-in" type="text" v-model="btnRadiusLocal">
|
||||
</div>
|
||||
<div class="radius-item">
|
||||
<label for="panelradius" class="theme-radius-lb">{{$t('settings.panelRadius')}}</label>
|
||||
<input id="panelradius" class="theme-radius-rn" type="range" v-model="panelRadiusLocal" max="50">
|
||||
<input id="panelradius-t" class="theme-radius-in" type="text" v-model="panelRadiusLocal">
|
||||
</div>
|
||||
<div class="radius-item">
|
||||
<label for="avatarradius" class="theme-radius-lb">{{$t('settings.avatarRadius')}}</label>
|
||||
<input id="avatarradius" class="theme-radius-rn" type="range" v-model="avatarRadiusLocal" max="28">
|
||||
<input id="avatarradius-t" class="theme-radius-in" type="green" v-model="avatarRadiusLocal">
|
||||
</div>
|
||||
<div class="radius-item">
|
||||
<label for="avataraltradius" class="theme-radius-lb">{{$t('settings.avatarAltRadius')}}</label>
|
||||
<input id="avataraltradius" class="theme-radius-rn" type="range" v-model="avatarAltRadiusLocal" max="28">
|
||||
<input id="avataraltradius-t" class="theme-radius-in" type="text" v-model="avatarAltRadiusLocal">
|
||||
</div>
|
||||
<div class="radius-item">
|
||||
<label for="attachmentradius" class="theme-radius-lb">{{$t('settings.attachmentRadius')}}</label>
|
||||
<input id="attachmentrradius" class="theme-radius-rn" type="range" v-model="attachmentRadiusLocal" max="50">
|
||||
<input id="attachmentradius-t" class="theme-radius-in" type="text" v-model="attachmentRadiusLocal">
|
||||
</div>
|
||||
<div class="radius-item">
|
||||
<label for="tooltipradius" class="theme-radius-lb">{{$t('settings.tooltipRadius')}}</label>
|
||||
<input id="tooltipradius" class="theme-radius-rn" type="range" v-model="tooltipRadiusLocal" max="20">
|
||||
<input id="tooltipradius-t" class="theme-radius-in" type="text" v-model="tooltipRadiusLocal">
|
||||
</div>
|
||||
</div>
|
||||
<div :style="{
|
||||
'--btnRadius': btnRadiusLocal + 'px',
|
||||
'--panelRadius': panelRadiusLocal + 'px',
|
||||
'--avatarRadius': avatarRadiusLocal + 'px',
|
||||
'--avatarAltRadius': avatarAltRadiusLocal + 'px',
|
||||
'--tooltipRadius': tooltipRadiusLocal + 'px',
|
||||
'--attachmentRadius': attachmentRadiusLocal + 'px'
|
||||
}">
|
||||
<div class="panel dummy">
|
||||
<div class="panel-heading" :style="{ 'background-color': btnColorLocal, 'color': textColorLocal }">Preview</div>
|
||||
<div class="panel-body theme-preview-content" :style="{ 'background-color': bgColorLocal, 'color': textColorLocal }">
|
||||
<div class="avatar" :style="{
|
||||
'border-radius': avatarRadiusLocal + 'px'
|
||||
}">
|
||||
( ͡° ͜ʖ ͡°)
|
||||
</div>
|
||||
<h4>Content</h4>
|
||||
<br>
|
||||
A bunch of more content and
|
||||
<a :style="{ 'color': linkColorLocal }">a nice lil' link</a>
|
||||
<a :style="{ color: linkColorLocal }">a nice lil' link</a>
|
||||
<i :style="{ color: blueColorLocal }" class="icon-reply"/>
|
||||
<i :style="{ color: greenColorLocal }" class="icon-retweet"/>
|
||||
<i :style="{ color: redColorLocal }" class="icon-cancel"/>
|
||||
<i :style="{ color: orangeColorLocal }" class="icon-star"/>
|
||||
<br>
|
||||
<button class="btn" :style="{ 'background-color': fgColorLocal, 'color': textColorLocal }">Button</button>
|
||||
<button class="btn" :style="{ 'background-color': btnColorLocal, 'color': textColorLocal }">Button</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn base02-background base04" @click="setCustomTheme">{{$t('general.apply')}}</button>
|
||||
<button class="btn" @click="setCustomTheme">{{$t('general.apply')}}</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="./style_switcher.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
.style-switcher {
|
||||
margin-right: 1em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.radius-container,
|
||||
.color-container {
|
||||
display: flex;
|
||||
|
||||
p {
|
||||
margin-top: 2em;
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
}
|
||||
.radius-container {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.color-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.radius-item,
|
||||
.color-item {
|
||||
min-width: 20em;
|
||||
display:flex;
|
||||
flex: 1 1 0;
|
||||
align-items: baseline;
|
||||
margin: 5px 6px 5px 0;
|
||||
min-width: 20em;
|
||||
display:flex;
|
||||
flex: 1 1 0;
|
||||
align-items: baseline;
|
||||
margin: 5px 6px 5px 0;
|
||||
|
||||
label {
|
||||
color: var(--faint, $fallback--faint);
|
||||
}
|
||||
}
|
||||
|
||||
.radius-item {
|
||||
flex-basis: auto;
|
||||
}
|
||||
|
||||
.theme-radius-rn,
|
||||
.theme-color-cl {
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
background: transparent;
|
||||
color: var(--faint, $fallback--faint);
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
.theme-color-cl,
|
||||
.theme-radius-in,
|
||||
.theme-color-in {
|
||||
margin-left: 4px;
|
||||
border-radius: 2px;
|
||||
border: 0;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.theme-color-in {
|
||||
padding: 5px;
|
||||
min-width: 4em;
|
||||
max-width: 7em;
|
||||
flex: 1;
|
||||
min-width: 4em;
|
||||
}
|
||||
|
||||
.theme-radius-in {
|
||||
min-width: 1em;
|
||||
}
|
||||
|
||||
.theme-radius-in,
|
||||
.theme-color-in {
|
||||
max-width: 7em;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.theme-radius-lb,
|
||||
.theme-color-lb {
|
||||
flex: 2;
|
||||
min-width: 7em;
|
||||
max-width: 10em;
|
||||
flex: 2;
|
||||
min-width: 7em;
|
||||
}
|
||||
|
||||
.theme-radius-lb{
|
||||
max-width: 50em;
|
||||
}
|
||||
|
||||
.theme-color-lb {
|
||||
max-width: 10em;
|
||||
}
|
||||
|
||||
.theme-color-cl {
|
||||
padding: 1px;
|
||||
max-width: 8em;
|
||||
align-self: stretch;
|
||||
height: 100%;
|
||||
flex: 0;
|
||||
min-width: 2em;
|
||||
cursor: pointer;
|
||||
}
|
||||
padding: 1px;
|
||||
max-width: 8em;
|
||||
height: 100%;
|
||||
flex: 0;
|
||||
min-width: 2em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.theme-preview-content {
|
||||
padding: 20px;
|
||||
}
|
||||
.theme-preview-content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.dummy {
|
||||
.avatar {
|
||||
background: linear-gradient(135deg, #b8e1fc 0%,#a9d2f3 10%,#90bae4 25%,#90bcea 37%,#90bff0 50%,#6ba8e5 51%,#a2daf5 83%,#bdf3fd 100%);
|
||||
color: black;
|
||||
text-align: center;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
width: 48px;
|
||||
float: left;
|
||||
margin-right: 1em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -105,7 +105,7 @@ const Timeline = {
|
|||
.then((friends) => this.$store.dispatch('addFriends', { friends }))
|
||||
},
|
||||
scrollLoad (e) {
|
||||
let height = Math.max(document.body.offsetHeight, document.body.scrollHeight)
|
||||
const height = Math.max(document.body.offsetHeight, document.body.scrollHeight)
|
||||
if (this.timeline.loading === false &&
|
||||
this.$store.state.config.autoLoad &&
|
||||
this.$el.offsetHeight > 0 &&
|
||||
|
|
|
@ -1,48 +1,50 @@
|
|||
<template>
|
||||
<div class="timeline panel panel-default" v-if="viewing == 'statuses'">
|
||||
<div class="panel-heading timeline-heading base02-background base04">
|
||||
<div class="panel-heading timeline-heading">
|
||||
<div class="title">
|
||||
{{title}}
|
||||
</div>
|
||||
<button @click.prevent="showNewStatuses" class="base05 base02-background loadmore-button" v-if="timeline.newStatusCount > 0 && !timelineError">
|
||||
<button @click.prevent="showNewStatuses" class="loadmore-button" v-if="timeline.newStatusCount > 0 && !timelineError">
|
||||
{{$t('timeline.show_new')}}{{newStatusCountStr}}
|
||||
</button>
|
||||
<div @click.prevent class="base06 error loadmore-text" v-if="timelineError">
|
||||
<div @click.prevent class="loadmore-error alert error" v-if="timelineError">
|
||||
{{$t('timeline.error_fetching')}}
|
||||
</div>
|
||||
<div @click.prevent class="base04 base02-background loadmore-text" v-if="!timeline.newStatusCount > 0 && !timelineError">
|
||||
<div @click.prevent class="loadmore-text" v-if="!timeline.newStatusCount > 0 && !timelineError">
|
||||
{{$t('timeline.up_to_date')}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body base01-background">
|
||||
<div class="panel-body">
|
||||
<div class="timeline">
|
||||
<status-or-conversation v-for="status in timeline.visibleStatuses" :key="status.id" v-bind:statusoid="status"></status-or-conversation>
|
||||
<a href="#" v-on:click.prevent='fetchOlderStatuses()' v-if="!timeline.loading">
|
||||
<div class="base02-background base03-border new-status-notification text-center">{{$t('timeline.load_older')}}</div>
|
||||
</a>
|
||||
<div class="base02-background base03-border new-status-notification text-center" v-else>...</div>
|
||||
<status-or-conversation v-for="status in timeline.visibleStatuses" :key="status.id" v-bind:statusoid="status" class="status-fadein"></status-or-conversation>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-footer">
|
||||
<a href="#" v-on:click.prevent='fetchOlderStatuses()' v-if="!timeline.loading">
|
||||
<div class="new-status-notification text-center panel-footer">{{$t('timeline.load_older')}}</div>
|
||||
</a>
|
||||
<div class="new-status-notification text-center panel-footer" v-else>...</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="timeline panel panel-default" v-else-if="viewing == 'followers'">
|
||||
<div class="panel-heading timeline-heading base02-background base04">
|
||||
<div class="panel-heading timeline-heading">
|
||||
<div class="title">
|
||||
{{$t('user_card.followers')}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body base01-background">
|
||||
<div class="panel-body">
|
||||
<div class="timeline">
|
||||
<user-card v-for="follower in followers" :key="follower.id" :user="follower" :showFollows="false"></user-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="timeline panel panel-default" v-else-if="viewing == 'friends'">
|
||||
<div class="panel-heading timeline-heading base02-background base04">
|
||||
<div class="panel-heading timeline-heading">
|
||||
<div class="title">
|
||||
{{$t('user_card.followees')}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body base01-background">
|
||||
<div class="panel-body">
|
||||
<div class="timeline">
|
||||
<user-card v-for="friend in friends" :key="friend.id" :user="friend" :showFollows="true"></user-card>
|
||||
</div>
|
||||
|
@ -52,51 +54,69 @@
|
|||
<script src="./timeline.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.timeline {
|
||||
.timeline-heading {
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
.title {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 70%;
|
||||
}
|
||||
.loadmore-button {
|
||||
position: absolute;
|
||||
right: 0.6em;
|
||||
font-size: 14px;
|
||||
|
||||
min-width: 6em;
|
||||
height: 1.8em;
|
||||
line-height: 100%;
|
||||
}
|
||||
.loadmore-text {
|
||||
position: absolute;
|
||||
right: 0.6em;
|
||||
font-size: 14px;
|
||||
min-width: 6em;
|
||||
border-radius: 5px;
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
padding: 0 0.5em 0 0.5em;
|
||||
opacity: 0.8;
|
||||
}
|
||||
.error {
|
||||
background-color: rgba(255, 48, 16, 0.65);
|
||||
}
|
||||
.timeline {
|
||||
.timeline-heading {
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.new-status-notification {
|
||||
position:relative;
|
||||
margin-top: -1px;
|
||||
font-size: 1.1em;
|
||||
border-width: 1px 0 0 0;
|
||||
border-style: solid;
|
||||
border-radius: 0 0 10px 10px;
|
||||
padding: 10px;
|
||||
z-index: 1;
|
||||
.title {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 70%;
|
||||
}
|
||||
|
||||
.loadmore-button {
|
||||
position: absolute;
|
||||
right: 0.6em;
|
||||
font-size: 14px;
|
||||
|
||||
min-width: 6em;
|
||||
height: 1.8em;
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
.loadmore-text {
|
||||
position: absolute;
|
||||
right: 0.6em;
|
||||
font-size: 14px;
|
||||
min-width: 6em;
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
padding: 0 0.5em 0 0.5em;
|
||||
opacity: 0.8;
|
||||
background-color: transparent;
|
||||
color: $fallback--faint;
|
||||
color: var(--faint, $fallback--faint);
|
||||
}
|
||||
|
||||
.loadmore-error {
|
||||
position: absolute;
|
||||
right: 0.6em;
|
||||
font-size: 14px;
|
||||
min-width: 6em;
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
padding: 0 0.25em 0 0.25em;
|
||||
margin: 0;
|
||||
color: $fallback--fg;
|
||||
color: var(--fg, $fallback--fg);
|
||||
}
|
||||
}
|
||||
|
||||
.new-status-notification {
|
||||
position:relative;
|
||||
margin-top: -1px;
|
||||
font-size: 1.1em;
|
||||
border-width: 1px 0 0 0;
|
||||
border-style: solid;
|
||||
border-color: var(--border, $fallback--border);
|
||||
padding: 10px;
|
||||
z-index: 1;
|
||||
background-color: $fallback--btn;
|
||||
background-color: var(--btn, $fallback--btn);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="card base00-background">
|
||||
<div class="card">
|
||||
<a href="#">
|
||||
<img @click.prevent="toggleUserExpanded" class="avatar" :src="user.profile_image_url">
|
||||
</a>
|
||||
|
@ -7,7 +7,7 @@
|
|||
<user-card-content :user="user" :switcher="false"></user-card-content>
|
||||
</div>
|
||||
<div class="name-and-screen-name" v-else>
|
||||
<div class="user-name">
|
||||
<div :title="user.name" class="user-name">
|
||||
{{ user.name }}
|
||||
<span class="follows-you" v-if="!userExpanded && showFollows && user.follows_you">
|
||||
{{ $t('user_card.follows_you') }}
|
||||
|
@ -21,54 +21,58 @@
|
|||
<script src="./user_card.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
.name-and-screen-name {
|
||||
margin-left: 0.7em;
|
||||
margin-top:0.0em;
|
||||
margin-right: 2em;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.name-and-screen-name {
|
||||
margin-left: 0.7em;
|
||||
margin-top:0.0em;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.follows-you {
|
||||
margin-left: 2em;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex: 1 0;
|
||||
padding-top: 0.6em;
|
||||
padding-right: 1em;
|
||||
padding-bottom: 0.6em;
|
||||
padding-left: 1em;
|
||||
border-bottom: 1px solid;
|
||||
margin: 0;
|
||||
border-bottom-color: $fallback--border;
|
||||
border-bottom-color: var(--border, $fallback--border);
|
||||
|
||||
.avatar {
|
||||
margin-top: 0.2em;
|
||||
width:32px;
|
||||
height: 32px;
|
||||
border-radius: $fallback--avatarAltRadius;
|
||||
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
|
||||
}
|
||||
}
|
||||
|
||||
.usercard {
|
||||
width: fill-available;
|
||||
margin: 0.2em 0 0.7em 0;
|
||||
border-radius: $fallback--panelRadius;
|
||||
border-radius: var(--panelRadius, $fallback--panelRadius);
|
||||
border-style: solid;
|
||||
border-color: $fallback--border;
|
||||
border-color: var(--border, $fallback--border);
|
||||
border-width: 1px;
|
||||
overflow: hidden;
|
||||
|
||||
.panel-heading {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.follows-you {
|
||||
margin-left: 2em;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.follows {
|
||||
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex: 1 0;
|
||||
padding-top: 0.6em;
|
||||
padding-right: 1em;
|
||||
padding-bottom: 0.6em;
|
||||
padding-left: 1em;
|
||||
border-bottom: 1px solid;
|
||||
margin: 0;
|
||||
border-bottom-color: inherit;
|
||||
|
||||
|
||||
.avatar {
|
||||
margin-top: 0.2em;
|
||||
width:32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.usercard {
|
||||
width: fill-available;
|
||||
margin: 0.2em 0 0.7em 0;
|
||||
border-radius: 10px;
|
||||
border-style: solid;
|
||||
border-color: inherit;
|
||||
border-width: 1px;
|
||||
overflow: hidden;
|
||||
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import StillImage from '../still-image/still-image.vue'
|
||||
import { hex2rgb } from '../../services/color_convert/color_convert.js'
|
||||
|
||||
export default {
|
||||
props: [ 'user', 'switcher' ],
|
||||
props: [ 'user', 'switcher', 'hideBio' ],
|
||||
computed: {
|
||||
headingStyle () {
|
||||
const color = this.$store.state.config.colors['base00']
|
||||
const color = this.$store.state.config.colors.bg
|
||||
if (color) {
|
||||
const rgb = hex2rgb(color)
|
||||
console.log(rgb)
|
||||
|
@ -14,11 +15,6 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
bodyStyle () {
|
||||
return {
|
||||
background: `linear-gradient(to bottom, rgba(0, 0, 0, 0), ${this.$store.state.config.colors['base00']} 80%)`
|
||||
}
|
||||
},
|
||||
isOtherUser () {
|
||||
return this.user.id !== this.$store.state.users.currentUser.id
|
||||
},
|
||||
|
@ -35,6 +31,9 @@ export default {
|
|||
return Math.round(this.user.statuses_count / days)
|
||||
}
|
||||
},
|
||||
components: {
|
||||
StillImage
|
||||
},
|
||||
methods: {
|
||||
followUser () {
|
||||
const store = this.$store
|
||||
|
|
|
@ -5,43 +5,45 @@
|
|||
<router-link to='/user-settings' style="float: right; margin-top:16px;" v-if="!isOtherUser">
|
||||
<i class="icon-cog usersettings"></i>
|
||||
</router-link>
|
||||
<a :href="user.statusnet_profile_url" target="_blank" style="float: right; margin-top:16px;" v-if="isOtherUser">
|
||||
<i class="icon-link-ext usersettings"></i>
|
||||
</a>
|
||||
<div class='container'>
|
||||
<router-link :to="{ name: 'user-profile', params: { id: user.id } }">
|
||||
<img :src="user.profile_image_url_original">
|
||||
<StillImage class="avatar" :src="user.profile_image_url_original"/>
|
||||
</router-link>
|
||||
<span class="glyphicon glyphicon-user"></span>
|
||||
<div class="name-and-screen-name">
|
||||
<div class='user-name'>{{user.name}}</div>
|
||||
<div :title="user.name" class='user-name'>{{user.name}}</div>
|
||||
<router-link :to="{ name: 'user-profile', params: { id: user.id } }">
|
||||
<div class='user-screen-name'>@{{user.screen_name}}</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="isOtherUser" class="user-interactions">
|
||||
<div v-if="user.follows_you && loggedIn" class="following base06">
|
||||
<div v-if="user.follows_you && loggedIn" class="following">
|
||||
{{ $t('user_card.follows_you') }}
|
||||
</div>
|
||||
<div class="follow" v-if="loggedIn">
|
||||
<span v-if="user.following">
|
||||
<!--Following them!-->
|
||||
<button @click="unfollowUser" class="base04 base00-background pressed">
|
||||
<button @click="unfollowUser" class="pressed">
|
||||
{{ $t('user_card.following') }}
|
||||
</button>
|
||||
</span>
|
||||
<span v-if="!user.following">
|
||||
<button @click="followUser" class="base05 base02-background">
|
||||
<button @click="followUser">
|
||||
{{ $t('user_card.follow') }}
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<div class='mute' v-if='isOtherUser'>
|
||||
<span v-if='user.muted'>
|
||||
<button @click="toggleMute" class="base04 base00-background pressed">
|
||||
<button @click="toggleMute" class="pressed">
|
||||
{{ $t('user_card.muted') }}
|
||||
</button>
|
||||
</span>
|
||||
<span v-if='!user.muted'>
|
||||
<button @click="toggleMute" class="base05 base02-background">
|
||||
<button @click="toggleMute">
|
||||
{{ $t('user_card.mute') }}
|
||||
</button>
|
||||
</span>
|
||||
|
@ -50,19 +52,19 @@
|
|||
<form method="POST" :action='subscribeUrl'>
|
||||
<input type="hidden" name="nickname" :value="user.screen_name">
|
||||
<input type="hidden" name="profile" value="">
|
||||
<button click="submit" class="remote-button base05 base02-background">
|
||||
<button click="submit" class="remote-button">
|
||||
{{ $t('user_card.remote_follow') }}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class='block' v-if='isOtherUser && loggedIn'>
|
||||
<span v-if='user.statusnet_blocking'>
|
||||
<button @click="unblockUser" class="base04 base00-background pressed">
|
||||
<button @click="unblockUser" class="pressed">
|
||||
{{ $t('user_card.blocked') }}
|
||||
</button>
|
||||
</span>
|
||||
<span v-if='!user.statusnet_blocking'>
|
||||
<button @click="blockUser" class="base05 base02-background">
|
||||
<button @click="blockUser">
|
||||
{{ $t('user_card.block') }}
|
||||
</button>
|
||||
</span>
|
||||
|
@ -70,25 +72,25 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body profile-panel-body" :style="bodyStyle">
|
||||
<div class="panel-body profile-panel-body">
|
||||
<div class="user-counts">
|
||||
<div class="user-count">
|
||||
<a href="#" v-on:click.prevent="setProfileView('statuses')" v-if="switcher"><h5 class="base05">{{ $t('user_card.statuses') }}</h5></a>
|
||||
<a href="#" v-on:click.prevent="setProfileView('statuses')" v-if="switcher"><h5>{{ $t('user_card.statuses') }}</h5></a>
|
||||
<h5 v-else>{{ $t('user_card.statuses') }}</h5>
|
||||
<span class="base05">{{user.statuses_count}} <br><span class="dailyAvg">{{dailyAvg}} {{ $t('user_card.per_day') }}</span></span>
|
||||
<span>{{user.statuses_count}} <br><span class="dailyAvg">{{dailyAvg}} {{ $t('user_card.per_day') }}</span></span>
|
||||
</div>
|
||||
<div class="user-count">
|
||||
<a href="#" v-on:click.prevent="setProfileView('friends')" v-if="switcher"><h5 class="base05">{{ $t('user_card.followees') }}</h5></a>
|
||||
<a href="#" v-on:click.prevent="setProfileView('friends')" v-if="switcher"><h5>{{ $t('user_card.followees') }}</h5></a>
|
||||
<h5 v-else>{{ $t('user_card.followees') }}</h5>
|
||||
<span class="base05">{{user.friends_count}}</span>
|
||||
<span>{{user.friends_count}}</span>
|
||||
</div>
|
||||
<div class="user-count">
|
||||
<a href="#" v-on:click.prevent="setProfileView('followers')" v-if="switcher"><h5 class="base05">{{ $t('user_card.followers') }}</h5></a>
|
||||
<a href="#" v-on:click.prevent="setProfileView('followers')" v-if="switcher"><h5>{{ $t('user_card.followers') }}</h5></a>
|
||||
<h5 v-else>{{ $t('user_card.followers') }}</h5>
|
||||
<span class="base05">{{user.followers_count}}</span>
|
||||
<span>{{user.followers_count}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<p>{{user.description}}</p>
|
||||
<p v-if="!hideBio">{{user.description}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -100,7 +102,8 @@
|
|||
|
||||
.profile-panel-background {
|
||||
background-size: cover;
|
||||
border-radius: 10px;
|
||||
border-radius: $fallback--panelRadius;
|
||||
border-radius: var(--panelRadius, $fallback--panelRadius);
|
||||
|
||||
.panel-heading {
|
||||
padding: 0.6em 0em;
|
||||
|
@ -112,39 +115,51 @@
|
|||
top: -0em;
|
||||
padding-top: 4em;
|
||||
word-wrap: break-word;
|
||||
background: linear-gradient(to bottom, rgba(0, 0, 0, 0), $fallback--bg 80%);
|
||||
background: linear-gradient(to bottom, rgba(0, 0, 0, 0), var(--bg, $fallback--bg) 80%)
|
||||
}
|
||||
|
||||
.user-info {
|
||||
color: white;
|
||||
color: white;
|
||||
padding: 0 16px 16px 16px;
|
||||
margin-bottom: -4em;
|
||||
|
||||
.usersettings {
|
||||
color: white;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.container{
|
||||
.container {
|
||||
padding: 16px 10px 4px 10px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex-direction: column;
|
||||
align-content: flex-start;
|
||||
justify-content: center;
|
||||
max-height: 56px;
|
||||
overflow: hidden;
|
||||
|
||||
.avatar {
|
||||
border-radius: $fallback--avatarRadius;
|
||||
border-radius: var(--avatarRadius, $fallback--avatarRadius);
|
||||
flex: 1 0 100%;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
box-shadow: 0px 1px 8px rgba(0,0,0,0.75);
|
||||
object-fit: cover;
|
||||
|
||||
&.animated::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
border-radius: 5px;
|
||||
flex: 1 0 100%;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
box-shadow: 0px 1px 8px rgba(0,0,0,0.75);
|
||||
object-fit: cover;
|
||||
&:hover .animated.avatar {
|
||||
canvas {
|
||||
display: none;
|
||||
}
|
||||
img {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
text-shadow: 0px 1px 1.5px rgba(0, 0, 0, 1.0);
|
||||
text-shadow: 0px 1px 1.5px rgba(0, 0, 0, 1.0);
|
||||
|
||||
.usersettings {
|
||||
color: #fff;
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
.name-and-screen-name {
|
||||
display: block;
|
||||
|
@ -152,18 +167,20 @@
|
|||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: 1 1 0;
|
||||
}
|
||||
|
||||
.user-name{
|
||||
color: white;
|
||||
}
|
||||
.user-name{
|
||||
color: white;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.user-screen-name {
|
||||
color: white;
|
||||
font-weight: lighter;
|
||||
font-size: 15px;
|
||||
padding-right: 0.1em;
|
||||
flex: 0 0 auto;
|
||||
color: white;
|
||||
font-weight: lighter;
|
||||
font-size: 15px;
|
||||
padding-right: 0.1em;
|
||||
}
|
||||
|
||||
.user-interactions {
|
||||
|
@ -219,23 +236,23 @@
|
|||
}
|
||||
|
||||
.user-counts {
|
||||
display: flex;
|
||||
line-height:16px;
|
||||
padding: 1em 1.5em 0em 1em;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
line-height:16px;
|
||||
padding: 1em 1.5em 0em 1em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.user-count {
|
||||
flex: 1;
|
||||
flex: 1;
|
||||
|
||||
h5 {
|
||||
font-size:1em;
|
||||
font-weight: bolder;
|
||||
margin: 0 0 0.25em;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
h5 {
|
||||
font-size:1em;
|
||||
font-weight: bolder;
|
||||
margin: 0 0 0.25em;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.dailyAvg {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<template>
|
||||
<span class="user-finder-container">
|
||||
<span class="finder-error base05" v-if="error">
|
||||
<span class="alert error" v-if="error">
|
||||
<i class="icon-cancel user-finder-icon" @click="dismissError"/>
|
||||
{{$t('finder.error_fetching_user')}}
|
||||
</span>
|
||||
<i class="icon-spin4 user-finder-icon animate-spin-slow" v-if="loading" />
|
||||
<a href="#" v-if="hidden"><i class="icon-user-plus user-finder-icon" @click.prevent.stop="toggleHidden"/></a>
|
||||
<span v-else>
|
||||
<input class="user-finder-input base03-border" @keyup.enter="findUser(username)" v-model="username" :placeholder="$t('finder.find_user')" id="user-finder-input" type="text"/>
|
||||
<input class="user-finder-input" @keyup.enter="findUser(username)" v-model="username" :placeholder="$t('finder.find_user')" id="user-finder-input" type="text"/>
|
||||
<i class="icon-cancel user-finder-icon" @click.prevent.stop="toggleHidden"/>
|
||||
</span>
|
||||
</span>
|
||||
|
@ -16,27 +16,16 @@
|
|||
<script src="./user_finder.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
.user-finder-container {
|
||||
height: 21px;
|
||||
max-width: 100%;
|
||||
}
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.user-finder-icon {
|
||||
}
|
||||
.user-finder-container {
|
||||
height: 29px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.user-finder-input {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: inherit;
|
||||
border-radius: 5px;
|
||||
max-width: 80%;
|
||||
padding: 0.1em 0.2em 0.2em 0.2em;
|
||||
}
|
||||
.user-finder-input {
|
||||
max-width: 80%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.finder-error {
|
||||
background-color: rgba(255, 48, 16, 0.65);
|
||||
margin: 0.35em;
|
||||
border-radius: 5px;
|
||||
padding: 0.25em;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<div class="user-panel">
|
||||
<div v-if='user' class="panel panel-default" style="overflow: visible;">
|
||||
<user-card-content :user="user" :switcher="false"></user-card-content>
|
||||
<div class="panel-footer base00-background">
|
||||
<user-card-content :user="user" :switcher="false" :hideBio="true"></user-card-content>
|
||||
<div class="panel-footer">
|
||||
<post-status-form v-if='user'></post-status-form>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -11,3 +11,11 @@
|
|||
</template>
|
||||
|
||||
<script src="./user_panel.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
.user-panel {
|
||||
.profile-panel-background .panel-heading {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<div v-if="user" class="user-profile panel panel-default base00-background">
|
||||
<div v-if="user" class="user-profile panel panel-default">
|
||||
<user-card-content :user="user" :switcher="true"></user-card-content>
|
||||
</div>
|
||||
<Timeline :title="$t('user_profile.timeline_title')" :timeline="timeline" :timeline-name="'user'" :user-id="userId"/>
|
||||
|
@ -15,7 +15,8 @@
|
|||
flex: 2;
|
||||
flex-basis: 500px;
|
||||
padding-bottom: 10px;
|
||||
border-radius: 10px;
|
||||
.panel-heading {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
<template>
|
||||
<div class="settings panel panel-default base00-background">
|
||||
<div class="panel-heading base02-background base04">
|
||||
<div class="settings panel panel-default">
|
||||
<div class="panel-heading">
|
||||
{{$t('settings.user_settings')}}
|
||||
</div>
|
||||
<div class="panel-body profile-edit">
|
||||
<div class="setting-item">
|
||||
<h3>{{$t('settings.name_bio')}}</h3>
|
||||
<p>{{$t('settings.name')}}</p>
|
||||
<input class='name-changer base03-border' id='username' v-model="newname"></input>
|
||||
<input class='name-changer' id='username' v-model="newname"></input>
|
||||
<p>{{$t('settings.bio')}}</p>
|
||||
<textarea class="bio base03-border" v-model="newbio"></textarea>
|
||||
<button :disabled='newname.length <= 0' class="btn btn-default base05 base02-background" @click="updateProfile">{{$t('general.submit')}}</button>
|
||||
<textarea class="bio" v-model="newbio"></textarea>
|
||||
<button :disabled='newname.length <= 0' class="btn btn-default" @click="updateProfile">{{$t('general.submit')}}</button>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<h3>{{$t('settings.avatar')}}</h3>
|
||||
|
@ -22,8 +22,8 @@
|
|||
<div>
|
||||
<input type="file" @change="uploadFile(0, $event)" ></input>
|
||||
</div>
|
||||
<i class="base09 icon-spin4 animate-spin" v-if="uploading[0]"></i>
|
||||
<button class="btn btn-default base05 base02-background" v-else-if="previews[0]" @click="submitAvatar">{{$t('general.submit')}}</button>
|
||||
<i class="icon-spin4 animate-spin" v-if="uploading[0]"></i>
|
||||
<button class="btn btn-default" v-else-if="previews[0]" @click="submitAvatar">{{$t('general.submit')}}</button>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<h3>{{$t('settings.profile_banner')}}</h3>
|
||||
|
@ -35,8 +35,8 @@
|
|||
<div>
|
||||
<input type="file" @change="uploadFile(1, $event)" ></input>
|
||||
</div>
|
||||
<i class="base09 icon-spin4 animate-spin uploading" v-if="uploading[1]"></i>
|
||||
<button class="btn btn-default base05 base02-background" v-else-if="previews[1]" @click="submitBanner">{{$t('general.submit')}}</button>
|
||||
<i class=" icon-spin4 animate-spin uploading" v-if="uploading[1]"></i>
|
||||
<button class="btn btn-default" v-else-if="previews[1]" @click="submitBanner">{{$t('general.submit')}}</button>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<h3>{{$t('settings.profile_background')}}</h3>
|
||||
|
@ -46,8 +46,8 @@
|
|||
<div>
|
||||
<input type="file" @change="uploadFile(2, $event)" ></input>
|
||||
</div>
|
||||
<i class="base09 icon-spin4 animate-spin uploading" v-if="uploading[2]"></i>
|
||||
<button class="btn btn-default base05 base02-background" v-else-if="previews[2]" @click="submitBg">{{$t('general.submit')}}</button>
|
||||
<i class=" icon-spin4 animate-spin uploading" v-if="uploading[2]"></i>
|
||||
<button class="btn btn-default" v-else-if="previews[2]" @click="submitBg">{{$t('general.submit')}}</button>
|
||||
</div>
|
||||
<div class="setting-item" v-if="pleromaBackend">
|
||||
<h3>{{$t('settings.follow_import')}}</h3>
|
||||
|
@ -55,8 +55,8 @@
|
|||
<form v-model="followImportForm">
|
||||
<input type="file" ref="followlist" v-on:change="followListChange"></input>
|
||||
</form>
|
||||
<i class="base09 icon-spin4 animate-spin uploading" v-if="uploading[3]"></i>
|
||||
<button class="btn btn-default base05 base02-background" v-else @click="importFollows">{{$t('general.submit')}}</button>
|
||||
<i class=" icon-spin4 animate-spin uploading" v-if="uploading[3]"></i>
|
||||
<button class="btn btn-default" v-else @click="importFollows">{{$t('general.submit')}}</button>
|
||||
<div v-if="followsImported">
|
||||
<i class="icon-cross" @click="dismissImported"></i>
|
||||
<p>{{$t('settings.follows_imported')}}</p>
|
||||
|
@ -75,24 +75,16 @@
|
|||
|
||||
<style lang="scss">
|
||||
.profile-edit {
|
||||
.name-changer {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-radius: 5px;
|
||||
padding: 0.2em 0.2em 0.2em 0.2em;
|
||||
}
|
||||
.name-submit {
|
||||
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||
}
|
||||
.bio {
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-radius: 5px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
input[type=file] {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.banner {
|
||||
max-width: 400px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.uploading {
|
||||
|
|
|
@ -20,14 +20,17 @@ const de = {
|
|||
muted: 'Stummgeschaltet',
|
||||
followers: 'Folgende',
|
||||
followees: 'Folgt',
|
||||
per_day: 'pro Tag'
|
||||
per_day: 'pro Tag',
|
||||
remote_follow: 'Remote Follow'
|
||||
},
|
||||
timeline: {
|
||||
show_new: 'Zeige Neuere',
|
||||
error_fetching: 'Fehler beim Laden',
|
||||
up_to_date: 'Aktuell',
|
||||
load_older: 'Lade ältere Beiträge',
|
||||
conversation: 'Unterhaltung'
|
||||
conversation: 'Unterhaltung',
|
||||
collapse: 'Einklappen',
|
||||
repeated: 'wiederholte'
|
||||
},
|
||||
settings: {
|
||||
user_settings: 'Benutzereinstellungen',
|
||||
|
@ -45,17 +48,28 @@ const de = {
|
|||
settings: 'Einstellungen',
|
||||
theme: 'Farbschema',
|
||||
presets: 'Voreinstellungen',
|
||||
theme_help: 'Benutze HTML Farbcodes (#aabbcc) um dein Farbschema anzupassen.',
|
||||
theme_help: 'Benutze HTML Farbcodes (#rrggbb) um dein Farbschema anzupassen.',
|
||||
background: 'Hintergrund',
|
||||
foreground: 'Vordergrund',
|
||||
text: 'Text',
|
||||
links: 'Links',
|
||||
cBlue: 'Blau (Antworten, Folgt dir)',
|
||||
cRed: 'Rot (Abbrechen)',
|
||||
cOrange: 'Orange (Favorisieren)',
|
||||
cGreen: 'Grün (Retweet)',
|
||||
btnRadius: 'Buttons',
|
||||
panelRadius: 'Panel',
|
||||
avatarRadius: 'Avatare',
|
||||
avatarAltRadius: 'Avatare (Benachrichtigungen)',
|
||||
tooltipRadius: 'Tooltips/Warnungen',
|
||||
attachmentRadius: 'Anhänge',
|
||||
filtering: 'Filter',
|
||||
filtering_explanation: 'Alle Beiträge die diese Wörter enthalten werden ausgeblendet. Ein Wort pro Zeile.',
|
||||
attachments: 'Anhänge',
|
||||
hide_attachments_in_tl: 'Anhänge in der Timeline ausblenden',
|
||||
hide_attachments_in_tl: 'Anhänge in der Zeitleiste ausblenden',
|
||||
hide_attachments_in_convo: 'Anhänge in Unterhaltungen ausblenden',
|
||||
nsfw_clickthrough: 'Aktiviere ausblendbares Overlay für als NSFW markierte Anhänge',
|
||||
nsfw_clickthrough: 'Aktiviere ausblendbares Overlay für Anhänge, die als NSFW markiert sind',
|
||||
stop_gifs: 'Play-on-hover GIFs',
|
||||
autoload: 'Aktiviere automatisches Laden von älteren Beiträgen beim scrollen',
|
||||
streaming: 'Aktiviere automatisches Laden (Streaming) von neuen Beiträgen',
|
||||
reply_link_preview: 'Aktiviere reply-link Vorschau bei Maus-Hover',
|
||||
|
@ -67,7 +81,9 @@ const de = {
|
|||
notifications: {
|
||||
notifications: 'Benachrichtigungen',
|
||||
read: 'Gelesen!',
|
||||
followed_you: 'folgt dir'
|
||||
followed_you: 'folgt dir',
|
||||
favorited_you: 'favorisierte deine Nachricht',
|
||||
repeated_you: 'wiederholte deine Nachricht'
|
||||
},
|
||||
login: {
|
||||
login: 'Anmelden',
|
||||
|
@ -94,6 +110,9 @@ const de = {
|
|||
general: {
|
||||
submit: 'Absenden',
|
||||
apply: 'Anwenden'
|
||||
},
|
||||
user_profile: {
|
||||
timeline_title: 'Beiträge'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,7 +139,9 @@ const fi = {
|
|||
error_fetching: 'Virhe ladatessa viestejä',
|
||||
up_to_date: 'Ajantasalla',
|
||||
load_older: 'Lataa vanhempia viestejä',
|
||||
conversation: 'Keskustelu'
|
||||
conversation: 'Keskustelu',
|
||||
collapse: 'Sulje',
|
||||
repeated: 'toisti'
|
||||
},
|
||||
settings: {
|
||||
user_settings: 'Käyttäjän asetukset',
|
||||
|
@ -156,7 +177,9 @@ const fi = {
|
|||
notifications: {
|
||||
notifications: 'Ilmoitukset',
|
||||
read: 'Lue!',
|
||||
followed_you: 'seuraa sinua'
|
||||
followed_you: 'seuraa sinua',
|
||||
favorited_you: 'tykkäsi viestistäsi',
|
||||
repeated_you: 'toisti viestisi'
|
||||
},
|
||||
login: {
|
||||
login: 'Kirjaudu sisään',
|
||||
|
@ -216,7 +239,9 @@ const en = {
|
|||
error_fetching: 'Error fetching updates',
|
||||
up_to_date: 'Up-to-date',
|
||||
load_older: 'Load older statuses',
|
||||
conversation: 'Conversation'
|
||||
conversation: 'Conversation',
|
||||
collapse: 'Collapse',
|
||||
repeated: 'repeated'
|
||||
},
|
||||
settings: {
|
||||
user_settings: 'User Settings',
|
||||
|
@ -234,29 +259,43 @@ const en = {
|
|||
settings: 'Settings',
|
||||
theme: 'Theme',
|
||||
presets: 'Presets',
|
||||
theme_help: 'Use hex color codes (#aabbcc) to customize your color theme.',
|
||||
theme_help: 'Use hex color codes (#rrggbb) to customize your color theme.',
|
||||
radii_help: 'Set up interface edge rounding (in pixels)',
|
||||
background: 'Background',
|
||||
foreground: 'Foreground',
|
||||
text: 'Text',
|
||||
links: 'Links',
|
||||
cBlue: 'Blue (Reply, follow)',
|
||||
cRed: 'Red (Cancel)',
|
||||
cOrange: 'Orange (Favorite)',
|
||||
cGreen: 'Green (Retweet)',
|
||||
btnRadius: 'Buttons',
|
||||
panelRadius: 'Panels',
|
||||
avatarRadius: 'Avatars',
|
||||
avatarAltRadius: 'Avatars (Notifications)',
|
||||
tooltipRadius: 'Tooltips/alerts',
|
||||
attachmentRadius: 'Attachments',
|
||||
filtering: 'Filtering',
|
||||
filtering_explanation: 'All statuses containing these words will be muted, one per line',
|
||||
attachments: 'Attachments',
|
||||
hide_attachments_in_tl: 'Hide attachments in timeline',
|
||||
hide_attachments_in_convo: 'Hide attachments in conversations',
|
||||
nsfw_clickthrough: 'Enable clickthrough NSFW attachment hiding',
|
||||
stop_gifs: 'Play-on-hover GIFs',
|
||||
autoload: 'Enable automatic loading when scrolled to the bottom',
|
||||
streaming: 'Enable automatic streaming of new posts when scrolled to the top',
|
||||
reply_link_preview: 'Enable reply-link preview on mouse hover',
|
||||
follow_import: 'Follow import',
|
||||
import_followers_from_a_csv_file: 'Import followers from a csv file',
|
||||
import_followers_from_a_csv_file: 'Import follows from a csv file',
|
||||
follows_imported: 'Follows imported! Processing them will take a while.',
|
||||
follow_import_error: 'Error importing followers'
|
||||
},
|
||||
notifications: {
|
||||
notifications: 'Notifications',
|
||||
read: 'Read!',
|
||||
followed_you: 'followed you'
|
||||
followed_you: 'followed you',
|
||||
favorited_you: 'favorited your status',
|
||||
repeated_you: 'repeated your status'
|
||||
},
|
||||
login: {
|
||||
login: 'Log in',
|
||||
|
@ -539,9 +578,13 @@ const ro = {
|
|||
}
|
||||
|
||||
const ja = {
|
||||
chat: {
|
||||
title: 'チャット'
|
||||
},
|
||||
nav: {
|
||||
chat: 'ローカルチャット',
|
||||
timeline: 'タイムライン',
|
||||
mentions: '通知',
|
||||
mentions: 'メンション',
|
||||
public_tl: '公開タイムライン',
|
||||
twkn: '接続しているすべてのネットワーク'
|
||||
},
|
||||
|
@ -549,22 +592,28 @@ const ja = {
|
|||
follows_you: 'フォローされました!',
|
||||
following: 'フォロー中!',
|
||||
follow: 'フォロー',
|
||||
statuses: 'ステータス',
|
||||
blocked: 'ブロック済み!',
|
||||
block: 'ブロック',
|
||||
statuses: '投稿',
|
||||
mute: 'ミュート',
|
||||
muted: 'ミュート済み',
|
||||
followers: 'フォロワー',
|
||||
followees: 'フォロー',
|
||||
per_day: '/日'
|
||||
per_day: '/日',
|
||||
remote_follow: 'リモートフォロー'
|
||||
},
|
||||
timeline: {
|
||||
show_new: '新しいものを表示',
|
||||
error_fetching: '更新の取得中にエラーが発生しました',
|
||||
show_new: '更新',
|
||||
error_fetching: '更新の取得中にエラーが発生しました。',
|
||||
up_to_date: '最新',
|
||||
load_older: '古いステータスを読み込む'
|
||||
load_older: '古い投稿を読み込む',
|
||||
conversation: '会話',
|
||||
collapse: '折り畳む',
|
||||
repeated: 'リピート'
|
||||
},
|
||||
settings: {
|
||||
user_settings: 'ユーザー設定',
|
||||
name_bio: '名前 & プロフィール',
|
||||
name_bio: '名前とプロフィール',
|
||||
name: '名前',
|
||||
bio: 'プロフィール',
|
||||
avatar: 'アバター',
|
||||
|
@ -577,23 +626,48 @@ const ja = {
|
|||
set_new_profile_background: '新しいプロフィールの背景を設定する',
|
||||
settings: '設定',
|
||||
theme: 'テーマ',
|
||||
presets: 'プリセット',
|
||||
theme_help: '16進数カラーコード (#aabbcc) を使用してカラーテーマをカスタマイズ出来ます。',
|
||||
radii_help: 'インターフェースの縁の丸さを設定する。',
|
||||
background: '背景',
|
||||
foreground: '前景',
|
||||
text: '文字',
|
||||
links: 'リンク',
|
||||
cBlue: '青 (返信, フォロー)',
|
||||
cRed: '赤 (キャンセル)',
|
||||
cOrange: 'オレンジ (お気に入り)',
|
||||
cGreen: '緑 (リツイート)',
|
||||
btnRadius: 'ボタン',
|
||||
panelRadius: 'パネル',
|
||||
avatarRadius: 'アバター',
|
||||
avatarAltRadius: 'アバター (通知)',
|
||||
tooltipRadius: 'ツールチップ/アラート',
|
||||
attachmentRadius: 'ファイル',
|
||||
filtering: 'フィルタリング',
|
||||
filtering_explanation: 'これらの単語を含むすべてのものはミュートされます、1行に1つのワードを入力してください',
|
||||
attachments: '添付ファイル',
|
||||
hide_attachments_in_tl: 'タイムラインの添付ファイルを隠す',
|
||||
hide_attachments_in_convo: '会話の中の添付ファイルを隠す',
|
||||
nsfw_clickthrough: 'NSFWファイルの非表示を有効にする',
|
||||
autoload: '下にスクロールした時に自動で読み込むようにする',
|
||||
reply_link_preview: 'マウスカーソルを重ねたときに返信リンクプレビューを表示するようにする'
|
||||
filtering_explanation: 'これらの単語を含むすべてのものがミュートされます。1行に1つの単語を入力してください。',
|
||||
attachments: 'ファイル',
|
||||
hide_attachments_in_tl: 'タイムラインのファイルを隠す。',
|
||||
hide_attachments_in_convo: '会話の中のファイルを隠す。',
|
||||
nsfw_clickthrough: 'NSFWファイルの非表示を有効にする。',
|
||||
stop_gifs: 'カーソルを重ねた時にGIFを再生する。',
|
||||
autoload: '下にスクロールした時に自動で読み込むようにする。',
|
||||
streaming: '上までスクロールした時に自動でストリーミングされるようにする。',
|
||||
reply_link_preview: 'マウスカーソルを重ねた時に返信のプレビューを表示するようにする。',
|
||||
follow_import: 'フォローインポート',
|
||||
import_followers_from_a_csv_file: 'CSVファイルからフォローをインポートする。',
|
||||
follows_imported: 'フォローがインポートされました!処理に少し時間がかかるかもしれません。',
|
||||
follow_import_error: 'フォロワーのインポート中にエラーが発生しました。'
|
||||
},
|
||||
notifications: {
|
||||
notifications: '通知',
|
||||
read: '読んだ!',
|
||||
followed_you: 'フォローされました'
|
||||
followed_you: 'フォローされました',
|
||||
favorited_you: 'あなたの投稿がお気に入りされました',
|
||||
repeated_you: 'あなたの投稿がリピートされました'
|
||||
},
|
||||
login: {
|
||||
login: 'ログイン',
|
||||
username: 'ユーザーネーム',
|
||||
username: 'ユーザー名',
|
||||
password: 'パスワード',
|
||||
register: '登録',
|
||||
logout: 'ログアウト'
|
||||
|
@ -607,43 +681,51 @@ const ja = {
|
|||
},
|
||||
post_status: {
|
||||
posting: '投稿',
|
||||
default: 'ちょうど羽田に着陸しました'
|
||||
default: 'ちょうどL.A.に着陸しました。'
|
||||
},
|
||||
finder: {
|
||||
find_user: 'ユーザー検索',
|
||||
error_fetching_user: 'ユーザー検索でエラーが発生しました'
|
||||
},
|
||||
general: {
|
||||
submit: '送信'
|
||||
submit: '送信',
|
||||
apply: '適用'
|
||||
},
|
||||
user_profile: {
|
||||
timeline_title: 'ユーザータイムライン'
|
||||
}
|
||||
}
|
||||
|
||||
const fr = {
|
||||
nav: {
|
||||
chat: 'Chat local',
|
||||
timeline: 'Journal',
|
||||
mentions: 'Notifications',
|
||||
public_tl: 'Statuts locaux',
|
||||
twkn: 'Le réseau connu'
|
||||
},
|
||||
user_card: {
|
||||
follows_you: 'Vous suit!',
|
||||
following: 'Suivi!',
|
||||
follows_you: 'Vous suit !',
|
||||
following: 'Suivi !',
|
||||
follow: 'Suivre',
|
||||
blocked: 'Bloqué',
|
||||
block: 'Bloquer',
|
||||
statuses: 'Statuts',
|
||||
mute: 'En sourdine',
|
||||
muted: 'Mis en sourdine',
|
||||
mute: 'Mettre en muet',
|
||||
muted: 'Mis en muet',
|
||||
followers: 'Vous suivent',
|
||||
followees: 'Suivis',
|
||||
per_day: 'par jour'
|
||||
per_day: 'par jour',
|
||||
remote_follow: 'Suivre d\'une autre instance'
|
||||
},
|
||||
timeline: {
|
||||
show_new: 'Afficher plus',
|
||||
error_fetching: 'Erreur en cherchant des mises à jours',
|
||||
up_to_date: 'À jour',
|
||||
load_older: 'Afficher plus',
|
||||
conversation: 'Conversation'
|
||||
conversation: 'Conversation',
|
||||
collapse: 'Fermer',
|
||||
repeated: 'a partagé'
|
||||
},
|
||||
settings: {
|
||||
user_settings: 'Paramètres utilisateur',
|
||||
|
@ -653,26 +735,51 @@ const fr = {
|
|||
avatar: 'Avatar',
|
||||
current_avatar: 'Votre avatar',
|
||||
set_new_avatar: 'Changer d\'avatar',
|
||||
profile_banner: 'Bannière du Profil',
|
||||
profile_banner: 'Bannière du profil',
|
||||
current_profile_banner: 'Bannière du profil',
|
||||
set_new_profile_banner: 'Changer de bannière',
|
||||
profile_background: 'Image de fond',
|
||||
set_new_profile_background: 'Changer l\'image de fond',
|
||||
set_new_profile_background: 'Changer d\'image de fond',
|
||||
settings: 'Paramètres',
|
||||
theme: 'Thème',
|
||||
filtering: 'Filtre',
|
||||
filtering_explanation: 'Tout les statuts contenant ces mots vont être mis sous silence, un mot par ligne.',
|
||||
filtering_explanation: 'Tout les statuts contenant ces mots vont être cachés, un mot par ligne.',
|
||||
attachments: 'Pièces jointes',
|
||||
hide_attachments_in_tl: 'Cacher les pièces jointes dans le journal',
|
||||
hide_attachments_in_convo: 'Cacher les pièces jointes dans les conversations',
|
||||
nsfw_clickthrough: 'Activer le clic pour afficher les images marquées comme contenu adulte ou sensible',
|
||||
autoload: 'Activer le chargement automatique une fois le bas de la page atteint',
|
||||
reply_link_preview: 'Activer un aperçu sur passage de la souris'
|
||||
reply_link_preview: 'Activer un aperçu d\'une réponse sur passage de la souris',
|
||||
presets: 'Thèmes prédéfinis',
|
||||
theme_help: 'Utilisez les codes de couleur hexadécimaux (#aabbcc) pour customiser les couleurs de votre thème.',
|
||||
background: 'Arrière plan',
|
||||
foreground: 'Premier plan',
|
||||
text: 'Texte',
|
||||
links: 'Liens',
|
||||
streaming: 'Active le défilement automatique de nouveaux statuts lorsqu\'on est au haut de la page',
|
||||
follow_import: 'Importer ses abonnements',
|
||||
import_followers_from_a_csv_file: 'Importer ses abonnements depuis un fichier csv',
|
||||
follows_imported: 'Abonnements importés ! Le traitement peut prendre un moment.',
|
||||
follow_import_error: 'Erreur lors de l\'importation des abonnements.',
|
||||
cBlue: 'Bleu (Répondre, suivre)',
|
||||
cRed: 'Rouge (Annuler)',
|
||||
cOrange: 'Orange (Aimer)',
|
||||
cGreen: 'Vert (Partager)',
|
||||
btnRadius: 'Boutons',
|
||||
panelRadius: 'Fenêtres',
|
||||
avatarRadius: 'Avatars',
|
||||
avatarAltRadius: 'Avatars (Notifications)',
|
||||
tooltipRadius: 'Info-bulles/alertes ',
|
||||
attachmentRadius: 'Pièces jointes',
|
||||
radii_help: 'Mettre en place l\'arondissement des coins de l\'interface (en pixels)',
|
||||
stop_gifs: 'Passer la souris sur un GIF pour l\'animer'
|
||||
},
|
||||
notifications: {
|
||||
notifications: 'Notfications',
|
||||
read: 'Lu!',
|
||||
followed_you: 'vous a suivi'
|
||||
notifications: 'Notifications',
|
||||
read: 'Lu !',
|
||||
followed_you: 'vous a suivi',
|
||||
favorited_you: 'a aimé votre statut',
|
||||
repeated_you: 'a partagé votre statut'
|
||||
},
|
||||
login: {
|
||||
login: 'Connexion',
|
||||
|
@ -683,10 +790,10 @@ const fr = {
|
|||
},
|
||||
registration: {
|
||||
registration: 'Inscription',
|
||||
fullname: 'Nom complet',
|
||||
email: 'Adresse courriel',
|
||||
fullname: 'Nom affiché',
|
||||
email: 'Adresse email',
|
||||
bio: 'Biographie',
|
||||
password_confirm: 'Confirmer le mot de passe'
|
||||
password_confirm: 'Confirmez le mot de passe'
|
||||
},
|
||||
post_status: {
|
||||
posting: 'Envoi en cours',
|
||||
|
@ -694,10 +801,14 @@ const fr = {
|
|||
},
|
||||
finder: {
|
||||
find_user: 'Chercher un utilisateur',
|
||||
error_fetching_user: 'Une erreur est survenue pendant la recherche d\'un utilisateur'
|
||||
error_fetching_user: 'Une erreur est survenue lors de la recherche de l\'utilisateur'
|
||||
},
|
||||
general: {
|
||||
submit: 'Envoyer'
|
||||
submit: 'Envoyer',
|
||||
apply: 'Appliquer'
|
||||
},
|
||||
user_profile: {
|
||||
timeline_title: 'Journal de l\'utilisateur'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -759,8 +870,131 @@ const it = {
|
|||
}
|
||||
}
|
||||
|
||||
const pl = {
|
||||
const oc = {
|
||||
chat: {
|
||||
title: 'Messatjariá'
|
||||
},
|
||||
nav: {
|
||||
chat: 'Chat local',
|
||||
timeline: 'Flux d’actualitat',
|
||||
mentions: 'Notificacions',
|
||||
public_tl: 'Estatuts locals',
|
||||
twkn: 'Lo malhum conegut'
|
||||
},
|
||||
user_card: {
|
||||
follows_you: 'Vos sèc !',
|
||||
following: 'Seguit !',
|
||||
follow: 'Seguir',
|
||||
blocked: 'Blocat',
|
||||
block: 'Blocar',
|
||||
statuses: 'Estatuts',
|
||||
mute: 'Amagar',
|
||||
muted: 'Amagat',
|
||||
followers: 'Seguidors',
|
||||
followees: 'Abonaments',
|
||||
per_day: 'per jorn',
|
||||
remote_follow: 'Seguir a distància'
|
||||
},
|
||||
timeline: {
|
||||
show_new: 'Ne veire mai',
|
||||
error_fetching: 'Error en cercant de mesas a jorn',
|
||||
up_to_date: 'Actualizat',
|
||||
load_older: 'Ne veire mai',
|
||||
conversation: 'Conversacion',
|
||||
collapse: 'Tampar',
|
||||
repeated: 'repetit'
|
||||
},
|
||||
settings: {
|
||||
user_settings: 'Paramètres utilizaire',
|
||||
name_bio: 'Nom & Bio',
|
||||
name: 'Nom',
|
||||
bio: 'Biografia',
|
||||
avatar: 'Avatar',
|
||||
current_avatar: 'Vòstre avatar actual',
|
||||
set_new_avatar: 'Cambiar l’avatar',
|
||||
profile_banner: 'Bandièra del perfil',
|
||||
current_profile_banner: 'Bandièra actuala del perfil',
|
||||
set_new_profile_banner: 'Cambiar de bandièra',
|
||||
profile_background: 'Imatge de fons',
|
||||
set_new_profile_background: 'Cambiar l’imatge de fons',
|
||||
settings: 'Paramètres',
|
||||
theme: 'Tèma',
|
||||
presets: 'Pre-enregistrats',
|
||||
theme_help: 'Emplegatz los còdis de color hex (#rrggbb) per personalizar vòstre tèma de color.',
|
||||
radii_help: 'Configurar los caires arredondits de l’interfàcia (en pixèls)',
|
||||
background: 'Rèire plan',
|
||||
foreground: 'Endavant',
|
||||
text: 'Tèxte',
|
||||
links: 'Ligams',
|
||||
cBlue: 'Blau (Respondre, seguir)',
|
||||
cRed: 'Roge (Anullar)',
|
||||
cOrange: 'Irange (Metre en favorit)',
|
||||
cGreen: 'Verd (Repartajar)',
|
||||
btnRadius: 'Botons',
|
||||
panelRadius: 'Panèls',
|
||||
avatarRadius: 'Avatars',
|
||||
avatarAltRadius: 'Avatars (Notificacions)',
|
||||
tooltipRadius: 'Astúcias/Alèrta',
|
||||
attachmentRadius: 'Pèças juntas',
|
||||
filtering: 'Filtre',
|
||||
filtering_explanation: 'Totes los estatuts amb aqueles mots seràn en silenci, un mot per linha.',
|
||||
attachments: 'Pèças juntas',
|
||||
hide_attachments_in_tl: 'Rescondre las pèças juntas',
|
||||
hide_attachments_in_convo: 'Rescondre las pèças juntas dins las conversacions',
|
||||
nsfw_clickthrough: 'Activar lo clic per mostrar los imatges marcats coma pels adults o sensibles',
|
||||
stop_gifs: 'Lançar los GIFs al subrevòl',
|
||||
autoload: 'Activar lo cargament automatic un còp arribat al cap de la pagina',
|
||||
streaming: 'Activar lo cargament automatic dels novèls estatus en anar amont',
|
||||
reply_link_preview: 'Activar l’apercebut en passar la mirga',
|
||||
follow_import: 'Importar los abonaments',
|
||||
import_followers_from_a_csv_file: 'Importar los seguidors d’un fichièr csv',
|
||||
follows_imported: 'Seguidors importats. Lo tractament pòt trigar una estona.',
|
||||
follow_import_error: 'Error en important los seguidors'
|
||||
},
|
||||
notifications: {
|
||||
notifications: 'Notficacions',
|
||||
read: 'Legit !',
|
||||
followed_you: 'vos a seguit',
|
||||
favorited_you: 'a aimat vòstre estatut',
|
||||
repeated_you: 'a repetit your vòstre estatut'
|
||||
},
|
||||
login: {
|
||||
login: 'Connexion',
|
||||
username: 'Nom d’utilizaire',
|
||||
password: 'Senhal',
|
||||
register: 'Se marcar',
|
||||
logout: 'Desconnexion'
|
||||
},
|
||||
registration: {
|
||||
registration: 'Inscripcion',
|
||||
fullname: 'Nom complèt',
|
||||
email: 'Adreça de corrièl',
|
||||
bio: 'Biografia',
|
||||
password_confirm: 'Confirmar lo senhal'
|
||||
},
|
||||
post_status: {
|
||||
posting: 'Mandadís',
|
||||
default: 'Escrivètz aquí vòstre estatut.'
|
||||
},
|
||||
finder: {
|
||||
find_user: 'Cercar un utilizaire',
|
||||
error_fetching_user: 'Error pendent la recèrca d’un utilizaire'
|
||||
},
|
||||
general: {
|
||||
submit: 'Mandar',
|
||||
apply: 'Aplicar'
|
||||
},
|
||||
user_profile: {
|
||||
timeline_title: 'Flux a l’utilizaire'
|
||||
}
|
||||
}
|
||||
|
||||
const pl = {
|
||||
chat: {
|
||||
title: 'Czat'
|
||||
},
|
||||
nav: {
|
||||
chat: 'Lokalny czat',
|
||||
timeline: 'Oś czasu',
|
||||
mentions: 'Wzmianki',
|
||||
public_tl: 'Publiczna oś czasu',
|
||||
|
@ -777,14 +1011,17 @@ const pl = {
|
|||
muted: 'Wyciszony',
|
||||
followers: 'Obserwujący',
|
||||
followees: 'Obserwowani',
|
||||
per_day: 'dziennie'
|
||||
per_day: 'dziennie',
|
||||
remote_follow: 'Zdalna obserwacja'
|
||||
},
|
||||
timeline: {
|
||||
show_new: 'Pokaż nowe',
|
||||
error_fetching: 'Błąd pobierania',
|
||||
up_to_date: 'Na bieżąco',
|
||||
load_older: 'Załaduj starsze statusy',
|
||||
conversation: 'Rozmowa'
|
||||
conversation: 'Rozmowa',
|
||||
collapse: 'Zwiń',
|
||||
repeated: 'powtórzono'
|
||||
},
|
||||
settings: {
|
||||
user_settings: 'Ustawienia użytkownika',
|
||||
|
@ -794,26 +1031,51 @@ const pl = {
|
|||
avatar: 'Awatar',
|
||||
current_avatar: 'Twój obecny awatar',
|
||||
set_new_avatar: 'Ustaw nowy awatar',
|
||||
profile_banner: 'Banner profilui',
|
||||
profile_banner: 'Banner profilu',
|
||||
current_profile_banner: 'Twój obecny banner profilu',
|
||||
set_new_profile_banner: 'Ustaw nowy banner profilu',
|
||||
profile_background: 'Tło profilu',
|
||||
set_new_profile_background: 'Ustaw nowe tło profilu',
|
||||
settings: 'Ustawienia',
|
||||
theme: 'Motyw',
|
||||
presets: 'Gotowe motywy',
|
||||
theme_help: 'Użyj kolorów w notacji szesnastkowej (#rrggbb), by stworzyć swój motyw.',
|
||||
radii_help: 'Ustaw zaokrąglenie krawędzi interfejsu (w pikselach)',
|
||||
background: 'Tło',
|
||||
foreground: 'Pierwszy plan',
|
||||
text: 'Tekst',
|
||||
links: 'Łącza',
|
||||
cBlue: 'Niebieski (odpowiedz, obserwuj)',
|
||||
cRed: 'Czerwony (anuluj)',
|
||||
cOrange: 'Pomarańczowy (ulubione)',
|
||||
cGreen: 'Zielony (powtórzenia)',
|
||||
btnRadius: 'Przyciski',
|
||||
panelRadius: 'Panele',
|
||||
avatarRadius: 'Awatary',
|
||||
avatarAltRadius: 'Awatary (powiadomienia)',
|
||||
tooltipRadius: 'Etykiety/alerty',
|
||||
attachmentRadius: 'Załączniki',
|
||||
filtering: 'Filtrowanie',
|
||||
filtering_explanation: 'Wszystkie statusy zawierające te słowa będą wyciszone. Jedno słowo na linijkę',
|
||||
attachments: 'Załączniki',
|
||||
hide_attachments_in_tl: 'Ukryj załączniki w osi czasu',
|
||||
hide_attachments_in_convo: 'Ukryj załączniki w rozmowach',
|
||||
nsfw_clickthrough: 'Włącz domyślne ukrywanie załączników o treści nieprzyzwoitej (NSFW)',
|
||||
stop_gifs: 'Odtwarzaj GIFy po najechaniu kursorem',
|
||||
autoload: 'Włącz automatyczne ładowanie po przewinięciu do końca strony',
|
||||
reply_link_preview: 'Włącz dymek z podglądem postu po najechaniu na znak odpowiedzi'
|
||||
streaming: 'Włącz automatycznie strumieniowanie nowych postów gdy na początku strony',
|
||||
reply_link_preview: 'Włącz dymek z podglądem postu po najechaniu na znak odpowiedzi',
|
||||
follow_import: 'Import obserwowanych',
|
||||
import_followers_from_a_csv_file: 'Importuj obserwowanych z pliku CSV',
|
||||
follows_imported: 'Obserwowani zaimportowani! Przetwarzanie może trochę potrwać.',
|
||||
follow_import_error: 'Błąd przy importowaniu obserwowanych'
|
||||
},
|
||||
notifications: {
|
||||
notifications: 'Powiadomienia',
|
||||
read: 'Przeczytane!',
|
||||
followed_you: 'obserwuje cię'
|
||||
followed_you: 'obserwuje cię',
|
||||
favorited_you: 'dodał twój status do ulubionych',
|
||||
repeated_you: 'powtórzył twój status'
|
||||
},
|
||||
login: {
|
||||
login: 'Zaloguj',
|
||||
|
@ -824,7 +1086,7 @@ const pl = {
|
|||
},
|
||||
registration: {
|
||||
registration: 'Rejestracja',
|
||||
fullname: 'Wyświetlane imię',
|
||||
fullname: 'Wyświetlana nazwa profilu',
|
||||
email: 'Email',
|
||||
bio: 'Bio',
|
||||
password_confirm: 'Potwierdzenie hasła'
|
||||
|
@ -838,7 +1100,11 @@ const pl = {
|
|||
error_fetching_user: 'Błąd przy pobieraniu profilu'
|
||||
},
|
||||
general: {
|
||||
submit: 'Wyślij'
|
||||
submit: 'Wyślij',
|
||||
apply: 'Zastosuj'
|
||||
},
|
||||
user_profile: {
|
||||
timeline_title: 'Oś czasu użytkownika'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -890,7 +1156,7 @@ const es = {
|
|||
settings: 'Ajustes',
|
||||
theme: 'Tema',
|
||||
presets: 'Por defecto',
|
||||
theme_help: 'Use códigos de color hexadecimales (#aabbcc) para personalizar su tema de colores.',
|
||||
theme_help: 'Use códigos de color hexadecimales (#rrggbb) para personalizar su tema de colores.',
|
||||
background: 'Segundo plano',
|
||||
foreground: 'Primer plano',
|
||||
text: 'Texto',
|
||||
|
@ -960,11 +1226,12 @@ const pt = {
|
|||
blocked: 'Bloqueado!',
|
||||
block: 'Bloquear',
|
||||
statuses: 'Postagens',
|
||||
mute: 'Mutar',
|
||||
muted: 'Mudo',
|
||||
mute: 'Silenciar',
|
||||
muted: 'Silenciado',
|
||||
followers: 'Seguidores',
|
||||
followees: 'Seguindo',
|
||||
per_day: 'por dia'
|
||||
per_day: 'por dia',
|
||||
remote_follow: 'Seguidor Remoto'
|
||||
},
|
||||
timeline: {
|
||||
show_new: 'Mostrar novas',
|
||||
|
@ -980,16 +1247,16 @@ const pt = {
|
|||
bio: 'Biografia',
|
||||
avatar: 'Avatar',
|
||||
current_avatar: 'Seu avatar atual',
|
||||
set_new_avatar: 'Mudar avatar',
|
||||
set_new_avatar: 'Alterar avatar',
|
||||
profile_banner: 'Capa de perfil',
|
||||
current_profile_banner: 'Sua capa de perfil atual',
|
||||
set_new_profile_banner: 'Mudar capa de perfil',
|
||||
set_new_profile_banner: 'Alterar capa de perfil',
|
||||
profile_background: 'Plano de fundo de perfil',
|
||||
set_new_profile_background: 'Mudar o plano de fundo de perfil',
|
||||
set_new_profile_background: 'Alterar o plano de fundo de perfil',
|
||||
settings: 'Configurações',
|
||||
theme: 'Tema',
|
||||
presets: 'Predefinições',
|
||||
theme_help: 'Use cores em códigos hexadecimais (#aabbcc) para personalizar seu esquema de cores.',
|
||||
theme_help: 'Use cores em código hexadecimal (#rrggbb) para personalizar seu esquema de cores.',
|
||||
background: 'Plano de Fundo',
|
||||
foreground: 'Primeiro Plano',
|
||||
text: 'Texto',
|
||||
|
@ -1004,9 +1271,9 @@ const pt = {
|
|||
streaming: 'Habilitar o fluxo automático de postagens quando ao topo da página',
|
||||
reply_link_preview: 'Habilitar a pré-visualização de link de respostas ao passar o mouse.',
|
||||
follow_import: 'Importar seguidas',
|
||||
import_followers_from_a_csv_file: 'Importe os perfis que tu segues apartir de um arquivo CSV',
|
||||
follows_imported: 'Seguidas importadas! O processamento das mesmas pode demorar um pouco.',
|
||||
follow_import_error: 'Erro ao importar seguidas'
|
||||
import_followers_from_a_csv_file: 'Importe seguidores a partir de um arquivo CSV',
|
||||
follows_imported: 'Seguidores importados! O processamento pode demorar um pouco.',
|
||||
follow_import_error: 'Erro ao importar seguidores'
|
||||
},
|
||||
notifications: {
|
||||
notifications: 'Notificações',
|
||||
|
@ -1023,7 +1290,7 @@ const pt = {
|
|||
registration: {
|
||||
registration: 'Registro',
|
||||
fullname: 'Nome para exibição',
|
||||
email: 'Correio eletônico',
|
||||
email: 'Correio eletrônico',
|
||||
bio: 'Biografia',
|
||||
password_confirm: 'Confirmação de senha'
|
||||
},
|
||||
|
@ -1071,7 +1338,9 @@ const ru = {
|
|||
error_fetching: 'Ошибка при обновлении',
|
||||
up_to_date: 'Обновлено',
|
||||
load_older: 'Загрузить старые статусы',
|
||||
conversation: 'Разговор'
|
||||
conversation: 'Разговор',
|
||||
collapse: 'Свернуть',
|
||||
repeated: 'повторил(а)'
|
||||
},
|
||||
settings: {
|
||||
user_settings: 'Настройки пользователя',
|
||||
|
@ -1089,16 +1358,28 @@ const ru = {
|
|||
settings: 'Настройки',
|
||||
theme: 'Тема',
|
||||
presets: 'Пресеты',
|
||||
theme_help: 'Используйте шестнадцатеричные коды цветов (#aabbcc) для настройки темы.',
|
||||
theme_help: 'Используйте шестнадцатеричные коды цветов (#rrggbb) для настройки темы.',
|
||||
radii_help: 'Округление краёв элементов интерфейса (в пикселях)',
|
||||
background: 'Фон',
|
||||
foreground: 'Передний план',
|
||||
text: 'Текст',
|
||||
links: 'Ссылки',
|
||||
cBlue: 'Ответить, читать',
|
||||
cRed: 'Отменить',
|
||||
cOrange: 'Нравится',
|
||||
cGreen: 'Повторить',
|
||||
btnRadius: 'Кнопки',
|
||||
panelRadius: 'Панели',
|
||||
avatarRadius: 'Аватары',
|
||||
avatarAltRadius: 'Аватары в уведомлениях',
|
||||
tooltipRadius: 'Всплывающие подсказки/уведомления',
|
||||
attachmentRadius: 'Прикреплённые файлы',
|
||||
filtering: 'Фильтрация',
|
||||
filtering_explanation: 'Все статусы, содержащие данные слова, будут игнорироваться, по одному в строке',
|
||||
attachments: 'Вложения',
|
||||
hide_attachments_in_tl: 'Прятать вложения в ленте',
|
||||
hide_attachments_in_convo: 'Прятать вложения в разговорах',
|
||||
stop_gifs: 'Проигрывать GIF анимации только при наведении',
|
||||
nsfw_clickthrough: 'Включить скрытие NSFW вложений',
|
||||
autoload: 'Включить автоматическую загрузку при прокрутке вниз',
|
||||
streaming: 'Включить автоматическую загрузку новых сообщений при прокрутке вверх',
|
||||
|
@ -1111,7 +1392,9 @@ const ru = {
|
|||
notifications: {
|
||||
notifications: 'Уведомления',
|
||||
read: 'Прочесть',
|
||||
followed_you: 'начал читать вас'
|
||||
followed_you: 'начал(а) читать вас',
|
||||
favorited_you: 'нравится ваш статус',
|
||||
repeated_you: 'повторил(а) ваш статус'
|
||||
},
|
||||
login: {
|
||||
login: 'Войти',
|
||||
|
@ -1154,6 +1437,7 @@ const messages = {
|
|||
ja,
|
||||
fr,
|
||||
it,
|
||||
oc,
|
||||
pl,
|
||||
es,
|
||||
pt,
|
||||
|
|
|
@ -1,7 +1,23 @@
|
|||
import { includes, remove, slice, sortBy, toInteger, each, find, flatten, maxBy, last, merge, max, isArray } from 'lodash'
|
||||
import { includes, remove, slice, sortBy, toInteger, each, find, flatten, maxBy, minBy, merge, last, isArray } from 'lodash'
|
||||
import apiService from '../services/api/api.service.js'
|
||||
// import parse from '../services/status_parser/status_parser.js'
|
||||
|
||||
const emptyTl = () => ({
|
||||
statuses: [],
|
||||
statusesObject: {},
|
||||
faves: [],
|
||||
visibleStatuses: [],
|
||||
visibleStatusesObject: {},
|
||||
newStatusCount: 0,
|
||||
maxId: 0,
|
||||
minVisibleId: 0,
|
||||
loading: false,
|
||||
followers: [],
|
||||
friends: [],
|
||||
viewing: 'statuses',
|
||||
flushMarker: 0
|
||||
})
|
||||
|
||||
export const defaultState = {
|
||||
allStatuses: [],
|
||||
allStatusesObject: {},
|
||||
|
@ -10,96 +26,12 @@ export const defaultState = {
|
|||
favorites: new Set(),
|
||||
error: false,
|
||||
timelines: {
|
||||
mentions: {
|
||||
statuses: [],
|
||||
statusesObject: {},
|
||||
faves: [],
|
||||
visibleStatuses: [],
|
||||
visibleStatusesObject: {},
|
||||
newStatusCount: 0,
|
||||
maxId: 0,
|
||||
minVisibleId: 0,
|
||||
loading: false,
|
||||
followers: [],
|
||||
friends: [],
|
||||
viewing: 'statuses',
|
||||
flushMarker: 0
|
||||
},
|
||||
public: {
|
||||
statuses: [],
|
||||
statusesObject: {},
|
||||
faves: [],
|
||||
visibleStatuses: [],
|
||||
visibleStatusesObject: {},
|
||||
newStatusCount: 0,
|
||||
maxId: 0,
|
||||
minVisibleId: 0,
|
||||
loading: false,
|
||||
followers: [],
|
||||
friends: [],
|
||||
viewing: 'statuses',
|
||||
flushMarker: 0
|
||||
},
|
||||
user: {
|
||||
statuses: [],
|
||||
statusesObject: {},
|
||||
faves: [],
|
||||
visibleStatuses: [],
|
||||
visibleStatusesObject: {},
|
||||
newStatusCount: 0,
|
||||
maxId: 0,
|
||||
minVisibleId: 0,
|
||||
loading: false,
|
||||
followers: [],
|
||||
friends: [],
|
||||
viewing: 'statuses',
|
||||
flushMarker: 0
|
||||
},
|
||||
publicAndExternal: {
|
||||
statuses: [],
|
||||
statusesObject: {},
|
||||
faves: [],
|
||||
visibleStatuses: [],
|
||||
visibleStatusesObject: {},
|
||||
newStatusCount: 0,
|
||||
maxId: 0,
|
||||
minVisibleId: 0,
|
||||
loading: false,
|
||||
followers: [],
|
||||
friends: [],
|
||||
viewing: 'statuses',
|
||||
flushMarker: 0
|
||||
},
|
||||
friends: {
|
||||
statuses: [],
|
||||
statusesObject: {},
|
||||
faves: [],
|
||||
visibleStatuses: [],
|
||||
visibleStatusesObject: {},
|
||||
newStatusCount: 0,
|
||||
maxId: 0,
|
||||
minVisibleId: 0,
|
||||
loading: false,
|
||||
followers: [],
|
||||
friends: [],
|
||||
viewing: 'statuses',
|
||||
flushMarker: 0
|
||||
},
|
||||
tag: {
|
||||
statuses: [],
|
||||
statusesObject: {},
|
||||
faves: [],
|
||||
visibleStatuses: [],
|
||||
visibleStatusesObject: {},
|
||||
newStatusCount: 0,
|
||||
maxId: 0,
|
||||
minVisibleId: 0,
|
||||
loading: false,
|
||||
followers: [],
|
||||
friends: [],
|
||||
viewing: 'statuses',
|
||||
flushMarker: 0
|
||||
}
|
||||
mentions: emptyTl(),
|
||||
public: emptyTl(),
|
||||
user: emptyTl(),
|
||||
publicAndExternal: emptyTl(),
|
||||
friends: emptyTl(),
|
||||
tag: emptyTl()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,6 +44,9 @@ export const prepareStatus = (status) => {
|
|||
// Parse nsfw tags
|
||||
if (status.nsfw === undefined) {
|
||||
status.nsfw = isNsfw(status)
|
||||
if (status.retweeted_status) {
|
||||
status.retweeted_status.nsfw = status.nsfw
|
||||
}
|
||||
}
|
||||
|
||||
// Set deleted flag
|
||||
|
@ -175,7 +110,6 @@ const sortTimeline = (timeline) => {
|
|||
timeline.visibleStatuses = sortBy(timeline.visibleStatuses, ({id}) => -id)
|
||||
timeline.statuses = sortBy(timeline.statuses, ({id}) => -id)
|
||||
timeline.minVisibleId = (last(timeline.visibleStatuses) || {}).id
|
||||
|
||||
return timeline
|
||||
}
|
||||
|
||||
|
@ -189,10 +123,11 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
|
|||
const allStatusesObject = state.allStatusesObject
|
||||
const timelineObject = state.timelines[timeline]
|
||||
|
||||
// Set the maxId to the new id if it's larger.
|
||||
const updateMaxId = ({id}) => {
|
||||
if (!timeline || noIdUpdate) { return false }
|
||||
timelineObject.maxId = max([id, timelineObject.maxId])
|
||||
const maxNew = statuses.length > 0 ? maxBy(statuses, 'id').id : 0
|
||||
const older = timeline && maxNew < timelineObject.maxId
|
||||
|
||||
if (timeline && !noIdUpdate && statuses.length > 0 && !older) {
|
||||
timelineObject.maxId = maxNew
|
||||
}
|
||||
|
||||
const addStatus = (status, showImmediately, addToTimeline = true) => {
|
||||
|
@ -200,8 +135,6 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
|
|||
status = result.item
|
||||
|
||||
if (result.new) {
|
||||
updateMaxId(status)
|
||||
|
||||
if (statusType(status) === 'retweet' && status.retweeted_status.user.id === user.id) {
|
||||
addNotification({ type: 'repeat', status: status.retweeted_status, action: status })
|
||||
}
|
||||
|
@ -246,7 +179,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
|
|||
const addNotification = ({type, status, action}) => {
|
||||
// Only add a new notification if we don't have one for the same action
|
||||
if (!find(state.notifications, (oldNotification) => oldNotification.action.id === action.id)) {
|
||||
state.notifications.push({type, status, action, seen: false})
|
||||
state.notifications.push({ type, status, action, seen: false })
|
||||
|
||||
if ('Notification' in window && window.Notification.permission === 'granted') {
|
||||
const title = action.user.name
|
||||
|
@ -317,7 +250,6 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
|
|||
// Only update if this is a new favorite.
|
||||
if (!state.favorites.has(favorite.id)) {
|
||||
state.favorites.add(favorite.id)
|
||||
updateMaxId(favorite)
|
||||
favoriteStatus(favorite)
|
||||
}
|
||||
},
|
||||
|
@ -330,7 +262,6 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
|
|||
},
|
||||
'deletion': (deletion) => {
|
||||
const uri = deletion.uri
|
||||
updateMaxId(deletion)
|
||||
|
||||
// Remove possible notification
|
||||
const status = find(allStatuses, {uri})
|
||||
|
@ -361,6 +292,9 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
|
|||
// Keep the visible statuses sorted
|
||||
if (timeline) {
|
||||
sortTimeline(timelineObject)
|
||||
if ((older || timelineObject.minVisibleId <= 0) && statuses.length > 0) {
|
||||
timelineObject.minVisibleId = minBy(statuses, 'id').id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -371,27 +305,12 @@ export const mutations = {
|
|||
|
||||
oldTimeline.newStatusCount = 0
|
||||
oldTimeline.visibleStatuses = slice(oldTimeline.statuses, 0, 50)
|
||||
oldTimeline.minVisibleId = last(oldTimeline.visibleStatuses).id
|
||||
oldTimeline.visibleStatusesObject = {}
|
||||
each(oldTimeline.visibleStatuses, (status) => { oldTimeline.visibleStatusesObject[status.id] = status })
|
||||
},
|
||||
clearTimeline (state, { timeline }) {
|
||||
const emptyTimeline = {
|
||||
statuses: [],
|
||||
statusesObject: {},
|
||||
faves: [],
|
||||
visibleStatuses: [],
|
||||
visibleStatusesObject: {},
|
||||
newStatusCount: 0,
|
||||
maxId: 0,
|
||||
minVisibleId: 0,
|
||||
loading: false,
|
||||
followers: [],
|
||||
friends: [],
|
||||
viewing: 'statuses',
|
||||
flushMarker: 0
|
||||
}
|
||||
|
||||
state.timelines[timeline] = emptyTimeline
|
||||
state.timelines[timeline] = emptyTl()
|
||||
},
|
||||
setFavorited (state, { status, value }) {
|
||||
const newStatus = state.allStatusesObject[status.id]
|
||||
|
|
|
@ -45,12 +45,8 @@ const setStyle = (href, commit) => {
|
|||
|
||||
const styleEl = document.createElement('style')
|
||||
head.appendChild(styleEl)
|
||||
const styleSheet = styleEl.sheet
|
||||
// const styleSheet = styleEl.sheet
|
||||
|
||||
styleSheet.insertRule(`a { color: ${colors['base08']}`, 'index-max')
|
||||
styleSheet.insertRule(`body { color: ${colors['base05']}`, 'index-max')
|
||||
styleSheet.insertRule(`.base05-border { border-color: ${colors['base05']}`, 'index-max')
|
||||
styleSheet.insertRule(`.base03-border { border-color: ${colors['base03']}`, 'index-max')
|
||||
body.style.display = 'initial'
|
||||
}
|
||||
|
||||
|
@ -68,37 +64,47 @@ const setColors = (col, commit) => {
|
|||
|
||||
const isDark = (col.text.r + col.text.g + col.text.b) > (col.bg.r + col.bg.g + col.bg.b)
|
||||
let colors = {}
|
||||
let radii = {}
|
||||
|
||||
let mod = 10
|
||||
if (isDark) {
|
||||
mod = mod * -1
|
||||
}
|
||||
const mod = isDark ? -10 : 10
|
||||
|
||||
colors.bg = rgb2hex(col.bg.r, col.bg.g, col.bg.b) // background
|
||||
colors.lightBg = rgb2hex((col.bg.r + col.fg.r) / 2, (col.bg.g + col.fg.g) / 2, (col.bg.b + col.fg.b) / 2) // hilighted bg
|
||||
colors.btn = rgb2hex(col.fg.r, col.fg.g, col.fg.b) // panels & buttons
|
||||
colors.border = rgb2hex(col.fg.r - mod, col.fg.g - mod, col.fg.b - mod) // borders
|
||||
colors.faint = rgb2hex(
|
||||
col.text.r * 0.45 + col.fg.r * 0.55,
|
||||
col.text.g * 0.45 + col.fg.g * 0.55,
|
||||
col.text.b * 0.45 + col.fg.b * 0.55) // faint text
|
||||
colors.fg = rgb2hex(col.text.r, col.text.g, col.text.b) // text
|
||||
colors.lightFg = rgb2hex(col.text.r - mod, col.text.g - mod, col.text.b - mod) // strong text
|
||||
|
||||
colors['base00'] = rgb2hex(col.bg.r, col.bg.g, col.bg.b) // background
|
||||
colors['base01'] = rgb2hex((col.bg.r + col.fg.r) / 2, (col.bg.g + col.fg.g) / 2, (col.bg.b + col.fg.b) / 2) // hilighted bg
|
||||
colors['base02'] = rgb2hex(col.fg.r, col.fg.g, col.fg.b) // panels & buttons
|
||||
colors['base03'] = rgb2hex(col.fg.r - mod, col.fg.g - mod, col.fg.b - mod) // borders
|
||||
colors['base04'] = rgb2hex(col.text.r + mod * 2, col.text.g + mod * 2, col.text.b + mod * 2) // faint text
|
||||
colors['base05'] = rgb2hex(col.text.r, col.text.g, col.text.b) // text
|
||||
colors['base06'] = rgb2hex(col.text.r - mod, col.text.g - mod, col.text.b - mod) // strong text
|
||||
colors['base07'] = rgb2hex(col.text.r - mod * 2, col.text.g - mod * 2, col.text.b - mod * 2)
|
||||
colors['base08'] = rgb2hex(col.link.r, col.link.g, col.link.b) // links
|
||||
colors['base09'] = rgb2hex((col.bg.r + col.text.r) / 2, (col.bg.g + col.text.g) / 2, (col.bg.b + col.text.b) / 2) // icons
|
||||
|
||||
const num = 10
|
||||
times(num, (n) => {
|
||||
const color = colors[`base0${num - 1 - n}`]
|
||||
styleSheet.insertRule(`.base0${num - 1 - n} { color: ${color}`, 'index-max')
|
||||
styleSheet.insertRule(`.base0${num - 1 - n}-background { background-color: ${color}`, 'index-max')
|
||||
})
|
||||
colors.link = rgb2hex(col.link.r, col.link.g, col.link.b) // links
|
||||
colors.icon = rgb2hex((col.bg.r + col.text.r) / 2, (col.bg.g + col.text.g) / 2, (col.bg.b + col.text.b) / 2) // icons
|
||||
|
||||
styleSheet.insertRule(`a { color: ${colors['base08']}`, 'index-max')
|
||||
styleSheet.insertRule(`body { color: ${colors['base05']}`, 'index-max')
|
||||
styleSheet.insertRule(`.base05-border { border-color: ${colors['base05']}`, 'index-max')
|
||||
styleSheet.insertRule(`.base03-border { border-color: ${colors['base03']}`, 'index-max')
|
||||
colors.cBlue = col.cBlue && rgb2hex(col.cBlue.r, col.cBlue.g, col.cBlue.b)
|
||||
colors.cRed = col.cRed && rgb2hex(col.cRed.r, col.cRed.g, col.cRed.b)
|
||||
colors.cGreen = col.cGreen && rgb2hex(col.cGreen.r, col.cGreen.g, col.cGreen.b)
|
||||
colors.cOrange = col.cOrange && rgb2hex(col.cOrange.r, col.cOrange.g, col.cOrange.b)
|
||||
|
||||
colors.cAlertRed = col.cRed && `rgba(${col.cRed.r}, ${col.cRed.g}, ${col.cRed.b}, .5)`
|
||||
|
||||
radii.btnRadius = col.btnRadius
|
||||
radii.panelRadius = col.panelRadius
|
||||
radii.avatarRadius = col.avatarRadius
|
||||
radii.avatarAltRadius = col.avatarAltRadius
|
||||
radii.tooltipRadius = col.tooltipRadius
|
||||
radii.attachmentRadius = col.attachmentRadius
|
||||
|
||||
styleSheet.toString()
|
||||
styleSheet.insertRule(`body { ${Object.entries(colors).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}`).join(';')} }`, 'index-max')
|
||||
styleSheet.insertRule(`body { ${Object.entries(radii).filter(([k, v]) => v).map(([k, v]) => `--${k}: ${v}px`).join(';')} }`, 'index-max')
|
||||
body.style.display = 'initial'
|
||||
|
||||
commit('setOption', { name: 'colors', value: colors })
|
||||
commit('setOption', { name: 'radii', value: radii })
|
||||
commit('setOption', { name: 'customTheme', value: col })
|
||||
}
|
||||
|
||||
|
@ -111,12 +117,23 @@ const setPreset = (val, commit) => {
|
|||
const fgRgb = hex2rgb(theme[2])
|
||||
const textRgb = hex2rgb(theme[3])
|
||||
const linkRgb = hex2rgb(theme[4])
|
||||
|
||||
const cRedRgb = hex2rgb(theme[5] || '#FF0000')
|
||||
const cGreenRgb = hex2rgb(theme[6] || '#00FF00')
|
||||
const cBlueRgb = hex2rgb(theme[7] || '#0000FF')
|
||||
const cOrangeRgb = hex2rgb(theme[8] || '#E3FF00')
|
||||
|
||||
const col = {
|
||||
bg: bgRgb,
|
||||
fg: fgRgb,
|
||||
text: textRgb,
|
||||
link: linkRgb
|
||||
link: linkRgb,
|
||||
cRed: cRedRgb,
|
||||
cBlue: cBlueRgb,
|
||||
cGreen: cGreenRgb,
|
||||
cOrange: cOrangeRgb
|
||||
}
|
||||
|
||||
// This is a hack, this function is only called during initial load.
|
||||
// We want to cancel loading the theme from config.json if we're already
|
||||
// loading a theme from the persisted state.
|
||||
|
|
|
@ -30,7 +30,7 @@ const fetchAndUpdate = ({store, credentials, timeline = 'friends', older = false
|
|||
|
||||
return apiService.fetchTimeline(args)
|
||||
.then((statuses) => {
|
||||
if (!older && statuses.length >= 20) {
|
||||
if (!older && statuses.length >= 20 && !timelineData.loading) {
|
||||
store.dispatch('queueFlush', { timeline: timeline, id: timelineData.maxId })
|
||||
}
|
||||
update({store, statuses, timeline, showImmediately})
|
||||
|
|
BIN
static/aurora_borealis.jpg
Normal file
BIN
static/aurora_borealis.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 628 KiB |
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 224 KiB |
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"theme": "pleroma-dark",
|
||||
"background": "/static/bg.jpg",
|
||||
"background": "/static/aurora_borealis.jpg",
|
||||
"logo": "/static/logo.png",
|
||||
"defaultPath": "/main/all",
|
||||
"chatDisabled": false,
|
||||
|
|
|
@ -95,6 +95,66 @@
|
|||
"css": "logout",
|
||||
"code": 59400,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "ccddff8e8670dcd130e3cb55fdfc2fd0",
|
||||
"css": "down-open",
|
||||
"code": 59401,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "44b9e75612c5fad5505edd70d071651f",
|
||||
"css": "attach",
|
||||
"code": 59402,
|
||||
"src": "entypo"
|
||||
},
|
||||
{
|
||||
"uid": "e15f0d620a7897e2035c18c80142f6d9",
|
||||
"css": "link-ext",
|
||||
"code": 61582,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "381da2c2f7fd51f8de877c044d7f439d",
|
||||
"css": "picture",
|
||||
"code": 59403,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "872d9516df93eb6b776cc4d94bd97dac",
|
||||
"css": "video",
|
||||
"code": 59404,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "399ef63b1e23ab1b761dfbb5591fa4da",
|
||||
"css": "right-open",
|
||||
"code": 59405,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "d870630ff8f81e6de3958ecaeac532f2",
|
||||
"css": "left-open",
|
||||
"code": 59406,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "fe6697b391355dec12f3d86d6d490397",
|
||||
"css": "up-open",
|
||||
"code": 59407,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "9c1376672bb4f1ed616fdd78a23667e9",
|
||||
"css": "comment-empty",
|
||||
"code": 61669,
|
||||
"src": "fontawesome"
|
||||
},
|
||||
{
|
||||
"uid": "cd21cbfb28ad4d903cede582157f65dc",
|
||||
"css": "bell",
|
||||
"code": 59408,
|
||||
"src": "fontawesome"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -8,13 +8,6 @@
|
|||
animation: spin 2s infinite linear;
|
||||
display: inline-block;
|
||||
}
|
||||
.animate-spin-slow {
|
||||
-moz-animation: spin 4s infinite linear;
|
||||
-o-animation: spin 4s infinite linear;
|
||||
-webkit-animation: spin 4s infinite linear;
|
||||
animation: spin 4s infinite linear;
|
||||
display: inline-block;
|
||||
}
|
||||
@-moz-keyframes spin {
|
||||
0% {
|
||||
-moz-transform: rotate(0deg);
|
||||
|
|
10
static/font/css/fontello-codes.css
vendored
10
static/font/css/fontello-codes.css
vendored
|
@ -8,9 +8,19 @@
|
|||
.icon-plus-squared:before { content: '\e806'; } /* '' */
|
||||
.icon-cog:before { content: '\e807'; } /* '' */
|
||||
.icon-logout:before { content: '\e808'; } /* '' */
|
||||
.icon-down-open:before { content: '\e809'; } /* '' */
|
||||
.icon-attach:before { content: '\e80a'; } /* '' */
|
||||
.icon-picture:before { content: '\e80b'; } /* '' */
|
||||
.icon-video:before { content: '\e80c'; } /* '' */
|
||||
.icon-right-open:before { content: '\e80d'; } /* '' */
|
||||
.icon-left-open:before { content: '\e80e'; } /* '' */
|
||||
.icon-up-open:before { content: '\e80f'; } /* '' */
|
||||
.icon-bell:before { content: '\e810'; } /* '' */
|
||||
.icon-spin3:before { content: '\e832'; } /* '' */
|
||||
.icon-spin4:before { content: '\e834'; } /* '' */
|
||||
.icon-link-ext:before { content: '\f08e'; } /* '' */
|
||||
.icon-menu:before { content: '\f0c9'; } /* '' */
|
||||
.icon-comment-empty:before { content: '\f0e5'; } /* '' */
|
||||
.icon-reply:before { content: '\f112'; } /* '' */
|
||||
.icon-binoculars:before { content: '\f1e5'; } /* '' */
|
||||
.icon-user-plus:before { content: '\f234'; } /* '' */
|
22
static/font/css/fontello-embedded.css
vendored
22
static/font/css/fontello-embedded.css
vendored
File diff suppressed because one or more lines are too long
10
static/font/css/fontello-ie7-codes.css
vendored
10
static/font/css/fontello-ie7-codes.css
vendored
|
@ -8,9 +8,19 @@
|
|||
.icon-plus-squared { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-cog { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-logout { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-down-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-attach { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-picture { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-video { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-right-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-left-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-up-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-bell { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-spin3 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-spin4 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-menu { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-comment-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-reply { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-binoculars { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-user-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
10
static/font/css/fontello-ie7.css
vendored
10
static/font/css/fontello-ie7.css
vendored
|
@ -19,9 +19,19 @@
|
|||
.icon-plus-squared { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-cog { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-logout { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-down-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-attach { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-picture { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-video { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-right-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-left-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-up-open { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-bell { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-spin3 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-spin4 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-link-ext { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-menu { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-comment-empty { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-reply { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-binoculars { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||
.icon-user-plus { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
24
static/font/css/fontello.css
vendored
24
static/font/css/fontello.css
vendored
|
@ -1,11 +1,11 @@
|
|||
@font-face {
|
||||
font-family: 'fontello';
|
||||
src: url('../font/fontello.eot?64848116');
|
||||
src: url('../font/fontello.eot?64848116#iefix') format('embedded-opentype'),
|
||||
url('../font/fontello.woff2?64848116') format('woff2'),
|
||||
url('../font/fontello.woff?64848116') format('woff'),
|
||||
url('../font/fontello.ttf?64848116') format('truetype'),
|
||||
url('../font/fontello.svg?64848116#fontello') format('svg');
|
||||
src: url('../font/fontello.eot?47566415');
|
||||
src: url('../font/fontello.eot?47566415#iefix') format('embedded-opentype'),
|
||||
url('../font/fontello.woff2?47566415') format('woff2'),
|
||||
url('../font/fontello.woff?47566415') format('woff'),
|
||||
url('../font/fontello.ttf?47566415') format('truetype'),
|
||||
url('../font/fontello.svg?47566415#fontello') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
|||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
@font-face {
|
||||
font-family: 'fontello';
|
||||
src: url('../font/fontello.svg?64848116#fontello') format('svg');
|
||||
src: url('../font/fontello.svg?47566415#fontello') format('svg');
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
@ -64,9 +64,19 @@
|
|||
.icon-plus-squared:before { content: '\e806'; } /* '' */
|
||||
.icon-cog:before { content: '\e807'; } /* '' */
|
||||
.icon-logout:before { content: '\e808'; } /* '' */
|
||||
.icon-down-open:before { content: '\e809'; } /* '' */
|
||||
.icon-attach:before { content: '\e80a'; } /* '' */
|
||||
.icon-picture:before { content: '\e80b'; } /* '' */
|
||||
.icon-video:before { content: '\e80c'; } /* '' */
|
||||
.icon-right-open:before { content: '\e80d'; } /* '' */
|
||||
.icon-left-open:before { content: '\e80e'; } /* '' */
|
||||
.icon-up-open:before { content: '\e80f'; } /* '' */
|
||||
.icon-bell:before { content: '\e810'; } /* '' */
|
||||
.icon-spin3:before { content: '\e832'; } /* '' */
|
||||
.icon-spin4:before { content: '\e834'; } /* '' */
|
||||
.icon-link-ext:before { content: '\f08e'; } /* '' */
|
||||
.icon-menu:before { content: '\f0c9'; } /* '' */
|
||||
.icon-comment-empty:before { content: '\f0e5'; } /* '' */
|
||||
.icon-reply:before { content: '\f112'; } /* '' */
|
||||
.icon-binoculars:before { content: '\f1e5'; } /* '' */
|
||||
.icon-user-plus:before { content: '\f234'; } /* '' */
|
|
@ -229,11 +229,11 @@ body {
|
|||
}
|
||||
@font-face {
|
||||
font-family: 'fontello';
|
||||
src: url('./font/fontello.eot?1253892');
|
||||
src: url('./font/fontello.eot?1253892#iefix') format('embedded-opentype'),
|
||||
url('./font/fontello.woff?1253892') format('woff'),
|
||||
url('./font/fontello.ttf?1253892') format('truetype'),
|
||||
url('./font/fontello.svg?1253892#fontello') format('svg');
|
||||
src: url('./font/fontello.eot?34497073');
|
||||
src: url('./font/fontello.eot?34497073#iefix') format('embedded-opentype'),
|
||||
url('./font/fontello.woff?34497073') format('woff'),
|
||||
url('./font/fontello.ttf?34497073') format('truetype'),
|
||||
url('./font/fontello.svg?34497073#fontello') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
@ -275,7 +275,7 @@ body {
|
|||
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="css/animation.css"><!--[if IE 7]><link rel="stylesheet" href="css/fontello-ie7.css"><![endif]-->
|
||||
<link rel="stylesheet" href="css/animation.css"><!--[if IE 7]><link rel="stylesheet" href="css/" + font.fontname + "-ie7.css"><![endif]-->
|
||||
<script>
|
||||
function toggleCodes(on) {
|
||||
var obj = document.getElementById('icons');
|
||||
|
@ -291,37 +291,50 @@ body {
|
|||
</head>
|
||||
<body>
|
||||
<div class="container header">
|
||||
<h1>
|
||||
fontello
|
||||
<small>font demo</small>
|
||||
</h1>
|
||||
<h1>fontello <small>font demo</small></h1>
|
||||
<label class="switch">
|
||||
<input type="checkbox" onclick="toggleCodes(this.checked)">show codes
|
||||
</label>
|
||||
</div>
|
||||
<div id="icons" class="container">
|
||||
<div class="container" id="icons">
|
||||
<div class="row">
|
||||
<div title="Code: 0xe800" class="the-icons span3"><i class="demo-icon icon-cancel"></i> <span class="i-name">icon-cancel</span><span class="i-code">0xe800</span></div>
|
||||
<div title="Code: 0xe801" class="the-icons span3"><i class="demo-icon icon-upload"></i> <span class="i-name">icon-upload</span><span class="i-code">0xe801</span></div>
|
||||
<div title="Code: 0xe802" class="the-icons span3"><i class="demo-icon icon-star"></i> <span class="i-name">icon-star</span><span class="i-code">0xe802</span></div>
|
||||
<div title="Code: 0xe803" class="the-icons span3"><i class="demo-icon icon-star-empty"></i> <span class="i-name">icon-star-empty</span><span class="i-code">0xe803</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe800"><i class="demo-icon icon-cancel"></i> <span class="i-name">icon-cancel</span><span class="i-code">0xe800</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe801"><i class="demo-icon icon-upload"></i> <span class="i-name">icon-upload</span><span class="i-code">0xe801</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe802"><i class="demo-icon icon-star"></i> <span class="i-name">icon-star</span><span class="i-code">0xe802</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe803"><i class="demo-icon icon-star-empty"></i> <span class="i-name">icon-star-empty</span><span class="i-code">0xe803</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div title="Code: 0xe804" class="the-icons span3"><i class="demo-icon icon-retweet"></i> <span class="i-name">icon-retweet</span><span class="i-code">0xe804</span></div>
|
||||
<div title="Code: 0xe805" class="the-icons span3"><i class="demo-icon icon-eye-off"></i> <span class="i-name">icon-eye-off</span><span class="i-code">0xe805</span></div>
|
||||
<div title="Code: 0xe806" class="the-icons span3"><i class="demo-icon icon-plus-squared"></i> <span class="i-name">icon-plus-squared</span><span class="i-code">0xe806</span></div>
|
||||
<div title="Code: 0xe807" class="the-icons span3"><i class="demo-icon icon-cog"></i> <span class="i-name">icon-cog</span><span class="i-code">0xe807</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe804"><i class="demo-icon icon-retweet"></i> <span class="i-name">icon-retweet</span><span class="i-code">0xe804</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe805"><i class="demo-icon icon-eye-off"></i> <span class="i-name">icon-eye-off</span><span class="i-code">0xe805</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe806"><i class="demo-icon icon-plus-squared"></i> <span class="i-name">icon-plus-squared</span><span class="i-code">0xe806</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe807"><i class="demo-icon icon-cog"></i> <span class="i-name">icon-cog</span><span class="i-code">0xe807</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div title="Code: 0xe808" class="the-icons span3"><i class="demo-icon icon-logout"></i> <span class="i-name">icon-logout</span><span class="i-code">0xe808</span></div>
|
||||
<div title="Code: 0xe832" class="the-icons span3"><i class="demo-icon icon-spin3 animate-spin"></i> <span class="i-name">icon-spin3</span><span class="i-code">0xe832</span></div>
|
||||
<div title="Code: 0xe834" class="the-icons span3"><i class="demo-icon icon-spin4 animate-spin"></i> <span class="i-name">icon-spin4</span><span class="i-code">0xe834</span></div>
|
||||
<div title="Code: 0xf0c9" class="the-icons span3"><i class="demo-icon icon-menu"></i> <span class="i-name">icon-menu</span><span class="i-code">0xf0c9</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe808"><i class="demo-icon icon-logout"></i> <span class="i-name">icon-logout</span><span class="i-code">0xe808</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe809"><i class="demo-icon icon-down-open"></i> <span class="i-name">icon-down-open</span><span class="i-code">0xe809</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe80a"><i class="demo-icon icon-attach"></i> <span class="i-name">icon-attach</span><span class="i-code">0xe80a</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe80b"><i class="demo-icon icon-picture"></i> <span class="i-name">icon-picture</span><span class="i-code">0xe80b</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div title="Code: 0xf112" class="the-icons span3"><i class="demo-icon icon-reply"></i> <span class="i-name">icon-reply</span><span class="i-code">0xf112</span></div>
|
||||
<div title="Code: 0xf1e5" class="the-icons span3"><i class="demo-icon icon-binoculars"></i> <span class="i-name">icon-binoculars</span><span class="i-code">0xf1e5</span></div>
|
||||
<div title="Code: 0xf234" class="the-icons span3"><i class="demo-icon icon-user-plus"></i> <span class="i-name">icon-user-plus</span><span class="i-code">0xf234</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe80c"><i class="demo-icon icon-video"></i> <span class="i-name">icon-video</span><span class="i-code">0xe80c</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe80d"><i class="demo-icon icon-right-open"></i> <span class="i-name">icon-right-open</span><span class="i-code">0xe80d</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe80e"><i class="demo-icon icon-left-open"></i> <span class="i-name">icon-left-open</span><span class="i-code">0xe80e</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe80f"><i class="demo-icon icon-up-open"></i> <span class="i-name">icon-up-open</span><span class="i-code">0xe80f</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="the-icons span3" title="Code: 0xe810"><i class="demo-icon icon-bell"></i> <span class="i-name">icon-bell</span><span class="i-code">0xe810</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe832"><i class="demo-icon icon-spin3 animate-spin"></i> <span class="i-name">icon-spin3</span><span class="i-code">0xe832</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xe834"><i class="demo-icon icon-spin4 animate-spin"></i> <span class="i-name">icon-spin4</span><span class="i-code">0xe834</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xf08e"><i class="demo-icon icon-link-ext"></i> <span class="i-name">icon-link-ext</span><span class="i-code">0xf08e</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="the-icons span3" title="Code: 0xf0c9"><i class="demo-icon icon-menu"></i> <span class="i-name">icon-menu</span><span class="i-code">0xf0c9</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xf0e5"><i class="demo-icon icon-comment-empty"></i> <span class="i-name">icon-comment-empty</span><span class="i-code">0xf0e5</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xf112"><i class="demo-icon icon-reply"></i> <span class="i-name">icon-reply</span><span class="i-code">0xf112</span></div>
|
||||
<div class="the-icons span3" title="Code: 0xf1e5"><i class="demo-icon icon-binoculars"></i> <span class="i-name">icon-binoculars</span><span class="i-code">0xf1e5</span></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="the-icons span3" title="Code: 0xf234"><i class="demo-icon icon-user-plus"></i> <span class="i-name">icon-user-plus</span><span class="i-code">0xf234</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container footer">Generated by <a href="http://fontello.com">fontello.com</a></div>
|
||||
|
|
Binary file not shown.
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Copyright (C) 2017 by original authors @ fontello.com</metadata>
|
||||
<metadata>Copyright (C) 2018 by original authors @ fontello.com</metadata>
|
||||
<defs>
|
||||
<font id="fontello" horiz-adv-x="1000" >
|
||||
<font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
|
||||
|
@ -24,12 +24,32 @@
|
|||
|
||||
<glyph glyph-name="logout" unicode="" d="M357 46q0-2 1-11t0-14-2-14-5-11-12-3h-178q-67 0-114 47t-47 114v392q0 67 47 114t114 47h178q8 0 13-5t5-13q0-2 1-11t0-15-2-13-5-11-12-3h-178q-37 0-63-26t-27-64v-392q0-37 27-63t63-27h174t6 0 7-2 4-3 4-5 1-8z m518 304q0-14-11-25l-303-304q-11-10-25-10t-25 10-11 25v161h-250q-14 0-25 11t-11 25v214q0 15 11 25t25 11h250v161q0 14 11 25t25 10 25-10l303-304q11-10 11-25z" horiz-adv-x="928.6" />
|
||||
|
||||
<glyph glyph-name="down-open" unicode="" d="M939 399l-414-413q-10-11-25-11t-25 11l-414 413q-11 11-11 26t11 25l93 92q10 11 25 11t25-11l296-296 296 296q11 11 25 11t26-11l92-92q11-11 11-25t-11-26z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="attach" unicode="" d="M244-140q-102 0-170 72-72 70-74 166t84 190l496 496q80 80 174 54 44-12 79-47t47-79q26-96-54-176l-474-474q-40-40-88-46-48-4-80 28-30 24-27 74t47 92l332 334q24 26 50 0t0-50l-332-332q-44-44-20-70 12-8 24-6 24 4 46 26l474 474q50 50 34 108-16 60-76 76-54 14-108-36l-494-494q-66-76-64-143t52-117q50-48 117-50t141 62l496 494q24 24 50 0 26-22 0-48l-496-496q-82-82-186-82z" horiz-adv-x="939" />
|
||||
|
||||
<glyph glyph-name="picture" unicode="" d="M357 529q0-45-31-76t-76-32-76 32-31 76 31 76 76 31 76-31 31-76z m572-215v-250h-786v107l178 179 90-89 285 285z m53 393h-893q-7 0-12-5t-6-13v-678q0-7 6-13t12-5h893q7 0 13 5t5 13v678q0 8-5 13t-13 5z m89-18v-678q0-37-26-63t-63-27h-893q-36 0-63 27t-26 63v678q0 37 26 63t63 27h893q37 0 63-27t26-63z" horiz-adv-x="1071.4" />
|
||||
|
||||
<glyph glyph-name="video" unicode="" d="M214-43v72q0 14-10 25t-25 10h-72q-14 0-25-10t-11-25v-72q0-14 11-25t25-11h72q14 0 25 11t10 25z m0 214v72q0 14-10 25t-25 11h-72q-14 0-25-11t-11-25v-72q0-14 11-25t25-10h72q14 0 25 10t10 25z m0 215v71q0 15-10 25t-25 11h-72q-14 0-25-11t-11-25v-71q0-15 11-25t25-11h72q14 0 25 11t10 25z m572-429v286q0 14-11 25t-25 11h-429q-14 0-25-11t-10-25v-286q0-14 10-25t25-11h429q15 0 25 11t11 25z m-572 643v71q0 15-10 26t-25 10h-72q-14 0-25-10t-11-26v-71q0-14 11-25t25-11h72q14 0 25 11t10 25z m786-643v72q0 14-11 25t-25 10h-71q-15 0-25-10t-11-25v-72q0-14 11-25t25-11h71q15 0 25 11t11 25z m-214 429v285q0 15-11 26t-25 10h-429q-14 0-25-10t-10-26v-285q0-15 10-25t25-11h429q15 0 25 11t11 25z m214-215v72q0 14-11 25t-25 11h-71q-15 0-25-11t-11-25v-72q0-14 11-25t25-10h71q15 0 25 10t11 25z m0 215v71q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-71q0-15 11-25t25-11h71q15 0 25 11t11 25z m0 214v71q0 15-11 26t-25 10h-71q-15 0-25-10t-11-26v-71q0-14 11-25t25-11h71q15 0 25 11t11 25z m71 89v-750q0-37-26-63t-63-26h-893q-36 0-63 26t-26 63v750q0 37 26 63t63 27h893q37 0 63-27t26-63z" horiz-adv-x="1071.4" />
|
||||
|
||||
<glyph glyph-name="right-open" unicode="" d="M618 361l-414-415q-11-10-25-10t-25 10l-93 93q-11 11-11 25t11 25l296 297-296 296q-11 11-11 25t11 25l93 93q10 11 25 11t25-11l414-414q10-11 10-25t-10-25z" horiz-adv-x="714.3" />
|
||||
|
||||
<glyph glyph-name="left-open" unicode="" d="M654 682l-297-296 297-297q10-10 10-25t-10-25l-93-93q-11-10-25-10t-25 10l-414 415q-11 10-11 25t11 25l414 414q10 11 25 11t25-11l93-93q10-10 10-25t-10-25z" horiz-adv-x="714.3" />
|
||||
|
||||
<glyph glyph-name="up-open" unicode="" d="M939 107l-92-92q-11-10-26-10t-25 10l-296 297-296-297q-11-10-25-10t-25 10l-93 92q-11 11-11 26t11 25l414 414q11 10 25 10t25-10l414-414q11-11 11-25t-11-26z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="bell" unicode="" d="M509-96q0 8-9 8-33 0-57 24t-23 57q0 9-9 9t-9-9q0-41 29-70t69-28q9 0 9 9z m-372 160h726q-149 168-149 465 0 28-13 58t-39 58-67 45-95 17-95-17-67-45-39-58-13-58q0-297-149-465z m827 0q0-29-21-50t-50-21h-250q0-59-42-101t-101-42-101 42-42 101h-250q-29 0-50 21t-21 50q28 24 51 49t47 67 42 89 27 115 11 145q0 84 66 157t171 89q-5 10-5 21 0 23 16 38t38 16 38-16 16-38q0-11-5-21 106-16 171-89t66-157q0-78 11-145t28-115 41-89 48-67 50-49z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="spin3" unicode="" d="M494 850c-266 0-483-210-494-472-1-19 13-20 13-20l84 0c16 0 19 10 19 18 10 199 176 358 378 358 107 0 205-45 273-118l-58-57c-11-12-11-27 5-31l247-50c21-5 46 11 37 44l-58 227c-2 9-16 22-29 13l-65-60c-89 91-214 148-352 148z m409-508c-16 0-19-10-19-18-10-199-176-358-377-358-108 0-205 45-274 118l59 57c10 12 10 27-5 31l-248 50c-21 5-46-11-37-44l58-227c2-9 16-22 30-13l64 60c89-91 214-148 353-148 265 0 482 210 493 473 1 18-13 19-13 19l-84 0z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="spin4" unicode="" d="M498 850c-114 0-228-39-320-116l0 0c173 140 428 130 588-31 134-134 164-332 89-495-10-29-5-50 12-68 21-20 61-23 84 0 3 3 12 15 15 24 71 180 33 393-112 539-99 98-228 147-356 147z m-409-274c-14 0-29-5-39-16-3-3-13-15-15-24-71-180-34-393 112-539 185-185 479-195 676-31l0 0c-173-140-428-130-589 31-134 134-163 333-89 495 11 29 6 50-12 68-11 11-27 17-44 16z" horiz-adv-x="1001" />
|
||||
|
||||
<glyph glyph-name="link-ext" unicode="" d="M786 332v-178q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h393q7 0 12-5t5-13v-36q0-8-5-13t-12-5h-393q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63v178q0 8 5 13t13 5h36q8 0 13-5t5-13z m214 482v-285q0-15-11-25t-25-11-25 11l-98 98-364-364q-5-6-13-6t-12 6l-64 64q-6 5-6 12t6 13l364 364-98 98q-11 11-11 25t11 25 25 11h285q15 0 25-11t11-25z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="menu" unicode="" d="M857 100v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 25t25 11h785q15 0 26-11t10-25z m0 286v-72q0-14-10-25t-26-10h-785q-15 0-25 10t-11 25v72q0 14 11 25t25 10h785q15 0 26-10t10-25z m0 285v-71q0-14-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 26t25 10h785q15 0 26-10t10-26z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="comment-empty" unicode="" d="M500 636q-114 0-213-39t-157-105-59-142q0-62 40-119t113-98l48-28-15-53q-13-51-39-97 85 36 154 96l24 21 32-3q38-5 72-5 114 0 213 39t157 105 59 142-59 142-157 105-213 39z m500-286q0-97-67-179t-182-130-251-48q-39 0-81 4-110-97-257-135-27-8-63-12h-3q-8 0-15 6t-9 15v1q-2 2 0 6t1 6 2 5l4 5t4 5 4 5q4 5 17 19t20 22 17 22 18 28 15 33 15 42q-88 50-138 123t-51 157q0 97 67 179t182 130 251 48 251-48 182-130 67-179z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="reply" unicode="" d="M1000 225q0-93-71-252-1-4-6-13t-7-17-7-12q-7-10-16-10-8 0-13 6t-5 14q0 5 1 15t2 13q3 38 3 69 0 56-10 101t-27 77-45 56-59 39-74 24-86 12-98 3h-125v-143q0-14-10-25t-26-11-25 11l-285 286q-11 10-11 25t11 25l285 286q11 10 25 10t26-10 10-25v-143h125q398 0 488-225 30-75 30-186z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="binoculars" unicode="" d="M393 671v-428q0-15-11-25t-25-11v-321q0-15-10-25t-26-11h-285q-15 0-25 11t-11 25v285l139 488q4 12 17 12h237z m178 0v-392h-142v392h142z m429-500v-285q0-15-11-25t-25-11h-285q-15 0-25 11t-11 25v321q-15 0-25 11t-11 25v428h237q13 0 17-12z m-589 661v-125h-197v125q0 8 5 13t13 5h161q8 0 13-5t5-13z m375 0v-125h-197v125q0 8 5 13t13 5h161q8 0 13-5t5-13z" horiz-adv-x="1000" />
|
||||
|
|
Before Width: | Height: | Size: 7 KiB After Width: | Height: | Size: 11 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"pleroma-dark": [ "Pleroma Dark", "#121a24", "#182230", "#b9b9ba", "#d8a070" ],
|
||||
"pleroma-light": [ "Pleroma Light", "#f2f4f6", "#dbe0e8", "#304055", "#f86f0f" ],
|
||||
"classic-dark": [ "Classic Dark", "#161c20", "#282e32", "#b9b9b9", "#baaa9c" ],
|
||||
"bird": [ "Bird", "#f8fafd", "#e6ecf0", "#14171a", "#0084b8"],
|
||||
"ir-black": [ "Ir Black", "#000000", "#242422", "#b5b3aa", "#ff6c60" ],
|
||||
"monokai": [ "Monokai", "#272822", "#383830", "#f8f8f2", "#f92672" ],
|
||||
"mammal": [ "Mammal", "#272c37", "#444b5d", "#f8f8f8", "#9bacc8" ]
|
||||
"pleroma-dark": [ "Pleroma Dark", "#121a24", "#182230", "#b9b9ba", "#d8a070", "#d31014", "#0fa00f", "#0095ff", "#ffa500" ],
|
||||
"pleroma-light": [ "Pleroma Light", "#f2f4f6", "#dbe0e8", "#304055", "#f86f0f", "#d31014", "#0fa00f", "#0095ff", "#ffa500" ],
|
||||
"classic-dark": [ "Classic Dark", "#161c20", "#282e32", "#b9b9b9", "#baaa9c", "#d31014", "#0fa00f", "#0095ff", "#ffa500" ],
|
||||
"bird": [ "Bird", "#f8fafd", "#e6ecf0", "#14171a", "#0084b8", "#e0245e", "#17bf63", "#1b95e0", "#fab81e"],
|
||||
"ir-black": [ "Ir Black", "#000000", "#242422", "#b5b3aa", "#ff6c60", "#FF6C60", "#A8FF60", "#96CBFE", "#FFFFB6" ],
|
||||
"monokai": [ "Monokai", "#272822", "#383830", "#f8f8f2", "#f92672", "#F92672", "#a6e22e", "#66d9ef", "#f4bf75" ],
|
||||
"mammal": [ "Mammal", "#272c37", "#444b5d", "#f8f8f8", "#9bacc8", "#7f3142", "#2bd850", "#2b90d9", "#ca8f04" ]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue