forked from AkkomaGang/akkoma-fe
Merge branch 'develop' into fedi-absturztau-be
This commit is contained in:
commit
07853ed322
48 changed files with 2662 additions and 715 deletions
|
@ -1,7 +1,7 @@
|
|||
# This file is a template, and might need editing before it works on your project.
|
||||
# Official framework image. Look for the different tagged releases at:
|
||||
# https://hub.docker.com/r/library/node/tags/
|
||||
image: node:8
|
||||
image: node:10
|
||||
|
||||
stages:
|
||||
- lint
|
||||
|
@ -14,6 +14,7 @@ lint:
|
|||
script:
|
||||
- yarn
|
||||
- npm run lint
|
||||
- npm run stylelint
|
||||
|
||||
test:
|
||||
stage: test
|
||||
|
|
19
.stylelintrc.json
Normal file
19
.stylelintrc.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"extends": [
|
||||
"stylelint-rscss/config",
|
||||
"stylelint-config-recommended",
|
||||
"stylelint-config-standard"
|
||||
],
|
||||
"rules": {
|
||||
"declaration-no-important": true,
|
||||
"rscss/no-descendant-combinator": false,
|
||||
"rscss/class-format": [
|
||||
true,
|
||||
{
|
||||
"component": "pascal-case",
|
||||
"variant": "^-[a-z]\\w+",
|
||||
"element": "^[a-z]\\w+"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
> A single column frontend designed for Pleroma.
|
||||
|
||||
![screenshot](https://i.imgur.com/DJVqSJ0.png)
|
||||
![screenshot](/uploads/796c5ecf985ed1e2b0943ee0df131ed0/DJVqSJ0.png)
|
||||
|
||||
# For Translators
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
"unit:watch": "karma start test/unit/karma.conf.js --single-run=false",
|
||||
"e2e": "node test/e2e/runner.js",
|
||||
"test": "npm run unit && npm run e2e",
|
||||
"stylelint": "npx stylelint src/components/status/status.scss",
|
||||
"lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs",
|
||||
"lint-fix": "eslint --fix --ext .js,.vue src test/unit/specs test/e2e/specs"
|
||||
},
|
||||
|
@ -22,8 +23,8 @@
|
|||
"cropperjs": "^1.4.3",
|
||||
"diff": "^3.0.1",
|
||||
"escape-html": "^1.0.3",
|
||||
"parse-link-header": "^1.0.1",
|
||||
"localforage": "^1.5.0",
|
||||
"parse-link-header": "^1.0.1",
|
||||
"phoenix": "^1.3.0",
|
||||
"portal-vue": "^2.1.4",
|
||||
"v-click-outside": "^2.1.1",
|
||||
|
@ -36,7 +37,6 @@
|
|||
"vuex": "^3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"karma-mocha-reporter": "^2.2.1",
|
||||
"@babel/core": "^7.7.5",
|
||||
"@babel/plugin-transform-runtime": "^7.7.6",
|
||||
"@babel/preset-env": "^7.7.6",
|
||||
|
@ -80,6 +80,7 @@
|
|||
"karma-coverage": "^1.1.1",
|
||||
"karma-firefox-launcher": "^1.1.0",
|
||||
"karma-mocha": "^1.2.0",
|
||||
"karma-mocha-reporter": "^2.2.1",
|
||||
"karma-sinon-chai": "^2.0.2",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-spec-reporter": "0.0.26",
|
||||
|
@ -101,6 +102,9 @@
|
|||
"shelljs": "^0.7.4",
|
||||
"sinon": "^2.1.0",
|
||||
"sinon-chai": "^2.8.0",
|
||||
"stylelint": "^13.6.1",
|
||||
"stylelint-config-standard": "^20.0.0",
|
||||
"stylelint-rscss": "^0.4.0",
|
||||
"url-loader": "^1.1.2",
|
||||
"vue-loader": "^14.0.0",
|
||||
"vue-style-loader": "^4.0.0",
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
@click="openModal"
|
||||
>
|
||||
<StillImage
|
||||
class="image"
|
||||
:referrerpolicy="referrerpolicy"
|
||||
:mimetype="attachment.mimetype"
|
||||
:src="attachment.large_thumb_url || attachment.url"
|
||||
|
@ -281,8 +282,11 @@
|
|||
}
|
||||
|
||||
.image-attachment {
|
||||
&,
|
||||
& .image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
display: none;
|
||||
|
|
|
@ -72,12 +72,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
.avatar.still-image {
|
||||
.Avatar {
|
||||
border-radius: $fallback--avatarAltRadius;
|
||||
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
|
||||
}
|
||||
|
||||
.status-body {
|
||||
.StatusContent {
|
||||
img.emoji {
|
||||
width: 1.4em;
|
||||
height: 1.4em;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
.chat-message-wrapper {
|
||||
&.hovered-message-chain {
|
||||
.animated.avatar {
|
||||
.animated.Avatar {
|
||||
canvas {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.still-image.avatar {
|
||||
.Avatar {
|
||||
width: 23px;
|
||||
height: 23px;
|
||||
margin-right: 0.5em;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div
|
||||
class="timeline panel-default"
|
||||
:class="[isExpanded ? 'panel' : 'panel-disabled']"
|
||||
class="Conversation"
|
||||
:class="{ '-expanded' : isExpanded, 'panel' : isExpanded }"
|
||||
>
|
||||
<div
|
||||
v-if="isExpanded"
|
||||
|
@ -28,7 +28,7 @@
|
|||
:replies="getReplies(status.id)"
|
||||
:in-profile="inProfile"
|
||||
:profile-user-id="profileUserId"
|
||||
class="status-fadein panel-body"
|
||||
class="conversation-status status-fadein panel-body"
|
||||
@goto="setHighlight"
|
||||
@toggleExpanded="toggleExpanded"
|
||||
/>
|
||||
|
@ -40,15 +40,28 @@
|
|||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.timeline {
|
||||
.panel-disabled {
|
||||
.status-el {
|
||||
.Conversation {
|
||||
.conversation-status {
|
||||
border-left: none;
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
border-color: var(--border, $fallback--border);
|
||||
border-bottom-color: var(--border, $fallback--border);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
&.-expanded {
|
||||
.conversation-status {
|
||||
border-color: $fallback--border;
|
||||
border-color: var(--border, $fallback--border);
|
||||
border-left: 4px solid $fallback--cRed;
|
||||
border-left: 4px solid var(--cRed, $fallback--cRed);
|
||||
}
|
||||
|
||||
.conversation-status: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);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { timelineNames } from '../timeline_menu/timeline_menu.js'
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
|
||||
const NavPanel = {
|
||||
|
@ -7,9 +8,17 @@ const NavPanel = {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
onTimelineRoute () {
|
||||
return !!timelineNames()[this.$route.name]
|
||||
},
|
||||
timelinesRoute () {
|
||||
if (this.$store.state.interface.lastTimeline) {
|
||||
return this.$store.state.interface.lastTimeline
|
||||
}
|
||||
return this.currentUser ? 'friends' : 'public-timeline'
|
||||
},
|
||||
...mapState({
|
||||
currentUser: state => state.users.currentUser,
|
||||
chat: state => state.chat.channel,
|
||||
followRequestCount: state => state.api.followRequests.length,
|
||||
privateMode: state => state.instance.private,
|
||||
federating: state => state.instance.federating,
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
<div class="nav-panel">
|
||||
<div class="panel panel-default">
|
||||
<ul>
|
||||
<li v-if="currentUser">
|
||||
<router-link :to="{ name: 'friends' }">
|
||||
<i class="button-icon icon-home-2" /> {{ $t("nav.timeline") }}
|
||||
<li v-if="currentUser || !privateMode">
|
||||
<router-link
|
||||
:to="{ name: timelinesRoute }"
|
||||
:class="onTimelineRoute && 'router-link-active'"
|
||||
>
|
||||
<i class="button-icon icon-home-2" /> {{ $t("nav.timelines") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li v-if="currentUser">
|
||||
|
@ -12,16 +15,6 @@
|
|||
<i class="button-icon icon-bell-alt" /> {{ $t("nav.interactions") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li v-if="currentUser">
|
||||
<router-link :to="{ name: 'dms', params: { username: currentUser.screen_name } }">
|
||||
<i class="button-icon icon-mail-alt" /> {{ $t("nav.dms") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li v-if="currentUser">
|
||||
<router-link :to="{ name: 'bookmarks'}">
|
||||
<i class="button-icon icon-bookmark" /> {{ $t("nav.bookmarks") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li v-if="currentUser && pleromaChatMessagesAvailable">
|
||||
<router-link :to="{ name: 'chats', params: { username: currentUser.screen_name } }">
|
||||
<div
|
||||
|
@ -44,16 +37,6 @@
|
|||
</span>
|
||||
</router-link>
|
||||
</li>
|
||||
<li v-if="currentUser || !privateMode">
|
||||
<router-link :to="{ name: 'public-timeline' }">
|
||||
<i class="button-icon icon-users" /> {{ $t("nav.public_tl") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li v-if="federating && (currentUser || !privateMode)">
|
||||
<router-link :to="{ name: 'public-external-timeline' }">
|
||||
<i class="button-icon icon-globe" /> {{ $t("nav.twkn") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'about' }">
|
||||
<i class="button-icon icon-info-circled" /> {{ $t("nav.about") }}
|
||||
|
|
52
src/components/notification/notification.scss
Normal file
52
src/components/notification/notification.scss
Normal file
|
@ -0,0 +1,52 @@
|
|||
// TODO Copypaste from Status, should unify it somehow
|
||||
.Notification {
|
||||
&.-muted {
|
||||
padding: 0.25em 0.6em;
|
||||
height: 1.2em;
|
||||
line-height: 1.2em;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
& .status-username,
|
||||
& .mute-thread,
|
||||
& .mute-words {
|
||||
word-wrap: normal;
|
||||
word-break: normal;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
& .status-username,
|
||||
& .mute-words {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.status-username {
|
||||
font-weight: normal;
|
||||
flex: 0 1 auto;
|
||||
margin-right: 0.2em;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.mute-thread {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.mute-words {
|
||||
flex: 1 0 5em;
|
||||
margin-left: 0.2em;
|
||||
|
||||
&::before {
|
||||
content: ' ';
|
||||
}
|
||||
}
|
||||
|
||||
.unmute {
|
||||
flex: 0 0 auto;
|
||||
margin-left: auto;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
<div v-else>
|
||||
<div
|
||||
v-if="needMute && !unmuted"
|
||||
class="container muted"
|
||||
class="Notification container -muted"
|
||||
>
|
||||
<small>
|
||||
<router-link :to="userProfileLink">
|
||||
|
@ -171,3 +171,4 @@
|
|||
</template>
|
||||
|
||||
<script src="./notification.js"></script>
|
||||
<style src="./notification.scss" lang="scss"></style>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
|
||||
&:hover .animated.avatar {
|
||||
&:hover .animated.Avatar {
|
||||
canvas {
|
||||
display: none;
|
||||
}
|
||||
|
@ -60,16 +60,8 @@
|
|||
height: 32px;
|
||||
}
|
||||
|
||||
.status-body {
|
||||
color: $fallback--faint;
|
||||
color: var(--faint, $fallback--faint);
|
||||
a {
|
||||
color: var(--faintLink);
|
||||
}
|
||||
.status-content a {
|
||||
color: var(--postFaintLink);
|
||||
}
|
||||
}
|
||||
--link: var(--faintLink);
|
||||
--text: var(--faint);
|
||||
}
|
||||
|
||||
.follow-request-accept {
|
||||
|
@ -106,7 +98,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
.status-el {
|
||||
/* TODO cleanup this */
|
||||
.Status {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<span class="result-percentage">
|
||||
{{ percentageForOption(option.votes_count) }}%
|
||||
</span>
|
||||
<span v-html="option.title_html"></span>
|
||||
<span v-html="option.title_html" />
|
||||
</div>
|
||||
<div
|
||||
class="result-fill"
|
||||
|
@ -96,6 +96,7 @@
|
|||
align-items: center;
|
||||
padding: 0.1em 0.25em;
|
||||
z-index: 1;
|
||||
word-break: break-word;
|
||||
}
|
||||
.result-percentage {
|
||||
width: 3.5em;
|
||||
|
|
|
@ -75,6 +75,7 @@ export default {
|
|||
deleteOption (index, event) {
|
||||
if (this.options.length > 2) {
|
||||
this.options.splice(index, 1)
|
||||
this.updatePollToParent()
|
||||
}
|
||||
},
|
||||
convertExpiryToUnit (unit, amount) {
|
||||
|
|
|
@ -18,7 +18,9 @@ const Popover = {
|
|||
// Takes a x/y object and tells how many pixels to offset from
|
||||
// anchor point on either axis
|
||||
offset: Object,
|
||||
// Additional styles you may want for the popover container
|
||||
// Replaces the classes you may want for the popover container.
|
||||
// Use 'popover-default' in addition to get the default popover
|
||||
// styles with your custom class.
|
||||
popoverClass: String
|
||||
},
|
||||
data () {
|
||||
|
@ -106,7 +108,7 @@ const Popover = {
|
|||
// single translate or translate3d resulted in blurry text.
|
||||
this.styles = {
|
||||
opacity: 1,
|
||||
transform: `translateX(${Math.floor(translateX)}px) translateY(${Math.floor(translateY)}px)`
|
||||
transform: `translateX(${Math.round(translateX)}px) translateY(${Math.round(translateY)}px)`
|
||||
}
|
||||
},
|
||||
showPopover () {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
ref="content"
|
||||
:style="styles"
|
||||
class="popover"
|
||||
:class="popoverClass"
|
||||
:class="popoverClass || 'popover-default'"
|
||||
>
|
||||
<slot
|
||||
name="content"
|
||||
|
@ -34,6 +34,9 @@
|
|||
z-index: 8;
|
||||
position: absolute;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.popover-default {
|
||||
transition: opacity 0.3s;
|
||||
|
||||
box-shadow: 1px 1px 4px rgba(0,0,0,.6);
|
||||
|
|
|
@ -79,10 +79,7 @@
|
|||
@click.stop.prevent="togglePreview"
|
||||
>
|
||||
{{ $t('post_status.preview') }}
|
||||
<i
|
||||
class="icon-down-open"
|
||||
:style="{ transform: showPreview ? 'rotate(0deg)' : 'rotate(-90deg)' }"
|
||||
/>
|
||||
<i :class="showPreview ? 'icon-left-open' : 'icon-right-open'" />
|
||||
</a>
|
||||
<i
|
||||
v-show="previewLoading"
|
||||
|
@ -146,6 +143,7 @@
|
|||
v-model="newStatus.status"
|
||||
:placeholder="placeholder || $t('post_status.default')"
|
||||
rows="1"
|
||||
cols="1"
|
||||
:disabled="posting"
|
||||
class="form-post-body"
|
||||
:class="{ 'scrollable-form': !!maxHeight }"
|
||||
|
@ -374,6 +372,7 @@
|
|||
}
|
||||
|
||||
.preview-heading {
|
||||
padding-left: 0.5em;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
||||
|
@ -385,14 +384,16 @@
|
|||
.preview-toggle {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
i {
|
||||
margin-left: 0.2em;
|
||||
font-size: 0.8em;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.icon-down-open {
|
||||
transition: transform 0.1s;
|
||||
}
|
||||
|
||||
.preview-container {
|
||||
|
|
|
@ -13,6 +13,13 @@
|
|||
* - 50px - leaving tiny amount of space so that titlebar + tiny amount of modal is visible
|
||||
*/
|
||||
transform: translateY(calc(((100vh - 100%) / 2 + 100%) - 50px));
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
/* For mobile, the modal takes 100% of the available screen.
|
||||
This ensures the minimized modal is always 50px above the browser bottom bar regardless of whether or not it is visible.
|
||||
*/
|
||||
transform: translateY(calc(100% - 50px));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +34,7 @@
|
|||
|
||||
@media all and (max-width: 800px) {
|
||||
max-width: 100vw;
|
||||
height: 100vh;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
>.panel-body {
|
||||
|
|
|
@ -49,6 +49,12 @@ const SideDrawer = {
|
|||
federating () {
|
||||
return this.$store.state.instance.federating
|
||||
},
|
||||
timelinesRoute () {
|
||||
if (this.$store.state.interface.lastTimeline) {
|
||||
return this.$store.state.interface.lastTimeline
|
||||
}
|
||||
return this.currentUser ? 'friends' : 'public-timeline'
|
||||
},
|
||||
...mapState({
|
||||
pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable
|
||||
}),
|
||||
|
|
|
@ -39,13 +39,18 @@
|
|||
<i class="button-icon icon-login" /> {{ $t("login.login") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
v-if="currentUser || !privateMode"
|
||||
@click="toggleDrawer"
|
||||
>
|
||||
<router-link :to="{ name: timelinesRoute }">
|
||||
<i class="button-icon icon-home-2" /> {{ $t("nav.timelines") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
v-if="currentUser && pleromaChatMessagesAvailable"
|
||||
@click="toggleDrawer"
|
||||
>
|
||||
<router-link :to="{ name: 'dms', params: { username: currentUser.screen_name } }">
|
||||
<i class="button-icon icon-mail-alt" /> {{ $t("nav.dms") }}
|
||||
</router-link>
|
||||
<router-link
|
||||
:to="{ name: 'chats', params: { username: currentUser.screen_name } }"
|
||||
style="position: relative"
|
||||
|
@ -59,34 +64,15 @@
|
|||
</span>
|
||||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
v-if="currentUser"
|
||||
@click="toggleDrawer"
|
||||
>
|
||||
</ul>
|
||||
<ul v-if="currentUser">
|
||||
<li @click="toggleDrawer">
|
||||
<router-link :to="{ name: 'interactions', params: { username: currentUser.screen_name } }">
|
||||
<i class="button-icon icon-bell-alt" /> {{ $t("nav.interactions") }}
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li
|
||||
v-if="currentUser"
|
||||
@click="toggleDrawer"
|
||||
>
|
||||
<router-link :to="{ name: 'friends' }">
|
||||
<i class="button-icon icon-home-2" /> {{ $t("nav.timeline") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
v-if="currentUser"
|
||||
@click="toggleDrawer"
|
||||
>
|
||||
<router-link :to="{ name: 'bookmarks'}">
|
||||
<i class="button-icon icon-bookmark" /> {{ $t("nav.bookmarks") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
v-if="currentUser && currentUser.locked"
|
||||
v-if="currentUser.locked"
|
||||
@click="toggleDrawer"
|
||||
>
|
||||
<router-link to="/friend-requests">
|
||||
|
@ -100,19 +86,11 @@
|
|||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
v-if="currentUser || !privateMode"
|
||||
v-if="chat"
|
||||
@click="toggleDrawer"
|
||||
>
|
||||
<router-link to="/main/public">
|
||||
<i class="button-icon icon-users" /> {{ $t("nav.public_tl") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
v-if="federating && (currentUser || !privateMode)"
|
||||
@click="toggleDrawer"
|
||||
>
|
||||
<router-link to="/main/all">
|
||||
<i class="button-icon icon-globe" /> {{ $t("nav.twkn") }}
|
||||
<router-link :to="{ name: 'chat' }">
|
||||
<i class="button-icon icon-chat" /> {{ $t("nav.chat") }}
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
414
src/components/status/status.scss
Normal file
414
src/components/status/status.scss
Normal file
|
@ -0,0 +1,414 @@
|
|||
|
||||
@import '../../_variables.scss';
|
||||
|
||||
$status-margin: 0.75em;
|
||||
|
||||
.Status {
|
||||
min-width: 0;
|
||||
|
||||
&:hover {
|
||||
--still-image-img: visible;
|
||||
--still-image-canvas: hidden;
|
||||
}
|
||||
|
||||
&.-focused {
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--selectedPost, $fallback--lightBg);
|
||||
color: $fallback--text;
|
||||
color: var(--selectedPostText, $fallback--text);
|
||||
|
||||
--lightText: var(--selectedPostLightText, $fallback--light);
|
||||
--faint: var(--selectedPostFaintText, $fallback--faint);
|
||||
--faintLink: var(--selectedPostFaintLink, $fallback--faint);
|
||||
--postLink: var(--selectedPostPostLink, $fallback--faint);
|
||||
--postFaintLink: var(--selectedPostFaintPostLink, $fallback--faint);
|
||||
--icon: var(--selectedPostIcon, $fallback--icon);
|
||||
}
|
||||
|
||||
.status-container {
|
||||
display: flex;
|
||||
padding: $status-margin;
|
||||
|
||||
&.-repeat {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.pin {
|
||||
padding: $status-margin $status-margin 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.left-side {
|
||||
margin-right: $status-margin;
|
||||
}
|
||||
|
||||
.right-side {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.usercard {
|
||||
margin-bottom: $status-margin;
|
||||
}
|
||||
|
||||
.status-username {
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
max-width: 85%;
|
||||
font-weight: bold;
|
||||
flex-shrink: 1;
|
||||
margin-right: 0.4em;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
.emoji {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
vertical-align: middle;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.status-favicon {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
margin-right: 0.4em;
|
||||
}
|
||||
|
||||
.status-heading {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.heading-name-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
line-height: 18px;
|
||||
|
||||
a {
|
||||
display: inline-block;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
|
||||
.account-name {
|
||||
min-width: 1.6em;
|
||||
margin-right: 0.4em;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
flex: 1 1 0;
|
||||
}
|
||||
|
||||
.heading-left {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.heading-right {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.timeago {
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
|
||||
.heading-reply-row {
|
||||
position: relative;
|
||||
align-content: baseline;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
max-width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.reply-to-and-accountname {
|
||||
display: flex;
|
||||
height: 18px;
|
||||
margin-right: 0.5em;
|
||||
max-width: 100%;
|
||||
|
||||
.reply-to-link {
|
||||
white-space: nowrap;
|
||||
word-break: break-word;
|
||||
text-overflow: ellipsis;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.icon-reply {
|
||||
// mirror the icon
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
}
|
||||
|
||||
& .reply-to-popover,
|
||||
& .reply-to-no-popover {
|
||||
min-width: 0;
|
||||
margin-right: 0.4em;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.reply-to-popover {
|
||||
.reply-to:hover::before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid var(--faint);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.faint-link:hover {
|
||||
// override default
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.-strikethrough {
|
||||
.reply-to::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid var(--faint);
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.reply-to {
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.reply-to-text {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin-left: 0.2em;
|
||||
}
|
||||
|
||||
.replies-separator {
|
||||
margin-left: 0.4em;
|
||||
}
|
||||
|
||||
.replies {
|
||||
line-height: 18px;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
& > * {
|
||||
margin-right: 0.4em;
|
||||
}
|
||||
}
|
||||
|
||||
.reply-link {
|
||||
height: 17px;
|
||||
}
|
||||
|
||||
.repeat-info {
|
||||
padding: 0.4em $status-margin;
|
||||
line-height: 22px;
|
||||
|
||||
.right-side {
|
||||
display: flex;
|
||||
align-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
i {
|
||||
padding: 0 0.2em;
|
||||
}
|
||||
}
|
||||
|
||||
.repeater-avatar {
|
||||
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
|
||||
margin-left: 28px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.repeater-name {
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 0;
|
||||
|
||||
.emoji {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
vertical-align: middle;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
.status-fadein {
|
||||
animation-duration: 0.4s;
|
||||
animation-name: fadein;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.status-actions {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
margin-top: $status-margin;
|
||||
|
||||
> * {
|
||||
max-width: 4em;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.button-reply {
|
||||
&:not(.-disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:not(.-disabled):hover,
|
||||
&.-active {
|
||||
color: $fallback--cBlue;
|
||||
color: var(--cBlue, $fallback--cBlue);
|
||||
}
|
||||
}
|
||||
|
||||
.muted {
|
||||
padding: 0.25em 0.6em;
|
||||
height: 1.2em;
|
||||
line-height: 1.2em;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
& .status-username,
|
||||
& .mute-thread,
|
||||
& .mute-words {
|
||||
word-wrap: normal;
|
||||
word-break: normal;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
& .status-username,
|
||||
& .mute-words {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.status-username {
|
||||
font-weight: normal;
|
||||
flex: 0 1 auto;
|
||||
margin-right: 0.2em;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.mute-thread {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.mute-words {
|
||||
flex: 1 0 5em;
|
||||
margin-left: 0.2em;
|
||||
|
||||
&::before {
|
||||
content: ' ';
|
||||
}
|
||||
}
|
||||
|
||||
.unmute {
|
||||
flex: 0 0 auto;
|
||||
margin-left: auto;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.reply-form {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.reply-body {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.favs-repeated-users {
|
||||
margin-top: $status-margin;
|
||||
}
|
||||
|
||||
.stats {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
.avatar-row {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
left: 0;
|
||||
background-color: var(--faint, $fallback--faint);
|
||||
}
|
||||
}
|
||||
|
||||
.stat-count {
|
||||
margin-right: $status-margin;
|
||||
user-select: none;
|
||||
|
||||
.stat-title {
|
||||
color: var(--faint, $fallback--faint);
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-weight: bolder;
|
||||
font-size: 16px;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
&:hover .stat-title {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
.repeater-avatar {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.avatar:not(.repeater-avatar) {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
// TODO define those other way somehow?
|
||||
// stylelint-disable rscss/class-format
|
||||
&.avatar-compact {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,8 +2,8 @@
|
|||
<!-- eslint-disable vue/no-v-html -->
|
||||
<div
|
||||
v-if="!hideStatus"
|
||||
class="status-el"
|
||||
:class="[{ 'status-el_focused': isFocused }, { 'status-conversation': inlineExpanded }]"
|
||||
class="Status"
|
||||
:class="[{ '-focused': isFocused }, { '-conversation': inlineExpanded }]"
|
||||
>
|
||||
<div
|
||||
v-if="error"
|
||||
|
@ -16,8 +16,8 @@
|
|||
/>
|
||||
</div>
|
||||
<template v-if="muted && !isPreview">
|
||||
<div class="media status container muted">
|
||||
<small class="username">
|
||||
<div class="status-csontainer muted">
|
||||
<small class="status-username">
|
||||
<i
|
||||
v-if="muted && retweet"
|
||||
class="button-icon icon-retweet"
|
||||
|
@ -54,7 +54,7 @@
|
|||
<template v-else>
|
||||
<div
|
||||
v-if="showPinned"
|
||||
class="status-pin"
|
||||
class="pin"
|
||||
>
|
||||
<i class="fa icon-pin faint" />
|
||||
<span class="faint">{{ $t('status.pinned') }}</span>
|
||||
|
@ -63,17 +63,17 @@
|
|||
v-if="retweet && !noHeading && !inConversation"
|
||||
:class="[repeaterClass, { highlighted: repeaterStyle }]"
|
||||
:style="[repeaterStyle]"
|
||||
class="media container retweet-info"
|
||||
class="status-container repeat-info"
|
||||
>
|
||||
<UserAvatar
|
||||
v-if="retweet"
|
||||
class="media-left"
|
||||
class="left-side repeater-avatar"
|
||||
:better-shadow="betterShadow"
|
||||
:user="statusoid.user"
|
||||
/>
|
||||
<div class="media-body faint">
|
||||
<div class="right-side faint">
|
||||
<span
|
||||
class="user-name"
|
||||
class="status-username repeater-name"
|
||||
:title="retweeter"
|
||||
>
|
||||
<router-link
|
||||
|
@ -95,14 +95,14 @@
|
|||
</div>
|
||||
|
||||
<div
|
||||
:class="[userClass, { highlighted: userStyle, 'is-retweet': retweet && !inConversation }]"
|
||||
:class="[userClass, { highlighted: userStyle, '-repeat': retweet && !inConversation }]"
|
||||
:style="[ userStyle ]"
|
||||
class="media status"
|
||||
class="status-container"
|
||||
:data-tags="tags"
|
||||
>
|
||||
<div
|
||||
v-if="!noHeading"
|
||||
class="media-left"
|
||||
class="left-side"
|
||||
>
|
||||
<router-link
|
||||
:to="userProfileLink"
|
||||
|
@ -115,29 +115,29 @@
|
|||
/>
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="status-body">
|
||||
<div class="right-side">
|
||||
<UserCard
|
||||
v-if="userExpanded"
|
||||
:user-id="status.user.id"
|
||||
:rounded="true"
|
||||
:bordered="true"
|
||||
class="status-usercard"
|
||||
class="usercard"
|
||||
/>
|
||||
<div
|
||||
v-if="!noHeading"
|
||||
class="media-heading"
|
||||
class="status-heading"
|
||||
>
|
||||
<div class="heading-name-row">
|
||||
<div class="name-and-account-name">
|
||||
<div class="heading-left">
|
||||
<h4
|
||||
v-if="status.user.name_html"
|
||||
class="user-name"
|
||||
class="status-username"
|
||||
:title="status.user.name"
|
||||
v-html="status.user.name_html"
|
||||
/>
|
||||
<h4
|
||||
v-else
|
||||
class="user-name"
|
||||
class="status-username"
|
||||
:title="status.user.name"
|
||||
>
|
||||
{{ status.user.name }}
|
||||
|
@ -150,8 +150,8 @@
|
|||
{{ status.user.screen_name }}
|
||||
</router-link>
|
||||
<img
|
||||
class="status-favicon"
|
||||
v-if="!!(status.user && status.user.favicon)"
|
||||
class="status-favicon"
|
||||
:src="status.user.favicon"
|
||||
>
|
||||
</div>
|
||||
|
@ -211,6 +211,7 @@
|
|||
:status-id="status.parent_visible && status.in_reply_to_status_id"
|
||||
class="reply-to-popover"
|
||||
style="min-width: 0"
|
||||
:class="{ '-strikethrough': !status.parent_visible }"
|
||||
>
|
||||
<a
|
||||
class="reply-to"
|
||||
|
@ -218,10 +219,9 @@
|
|||
:aria-label="$t('tool_tip.reply')"
|
||||
@click.prevent="gotoOriginal(status.in_reply_to_status_id)"
|
||||
>
|
||||
<i class="button-icon icon-reply" />
|
||||
<i class="button-icon reply-button icon-reply" />
|
||||
<span
|
||||
class="faint-link reply-to-text"
|
||||
:class="{ 'strikethrough': !status.parent_visible }"
|
||||
>
|
||||
{{ $t('status.reply_to') }}
|
||||
</span>
|
||||
|
@ -229,11 +229,12 @@
|
|||
</StatusPopover>
|
||||
<span
|
||||
v-else
|
||||
class="reply-to"
|
||||
class="reply-to-no-popover"
|
||||
>
|
||||
<span class="reply-to-text">{{ $t('status.reply_to') }}</span>
|
||||
</span>
|
||||
<router-link
|
||||
class="reply-to-link"
|
||||
:title="replyToName"
|
||||
:to="replyProfileLink"
|
||||
>
|
||||
|
@ -317,19 +318,19 @@
|
|||
|
||||
<div
|
||||
v-if="!noHeading && !isPreview"
|
||||
class="status-actions media-body"
|
||||
class="status-actions"
|
||||
>
|
||||
<div>
|
||||
<i
|
||||
v-if="loggedIn"
|
||||
class="button-icon icon-reply"
|
||||
class="button-icon button-reply icon-reply"
|
||||
:title="$t('tool_tip.reply')"
|
||||
:class="{'button-icon-active': replying}"
|
||||
:class="{'-active': replying}"
|
||||
@click.prevent="toggleReplying"
|
||||
/>
|
||||
<i
|
||||
v-else
|
||||
class="button-icon button-icon-disabled icon-reply"
|
||||
class="button-icon button-reply -disabled icon-reply"
|
||||
:title="$t('tool_tip.reply')"
|
||||
/>
|
||||
<span v-if="status.replies_count > 0">{{ status.replies_count }}</span>
|
||||
|
@ -357,7 +358,7 @@
|
|||
</div>
|
||||
<div
|
||||
v-if="replying"
|
||||
class="container"
|
||||
class="status-container reply-form"
|
||||
>
|
||||
<PostStatusForm
|
||||
class="reply-body"
|
||||
|
@ -375,439 +376,4 @@
|
|||
</template>
|
||||
|
||||
<script src="./status.js" ></script>
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
|
||||
$status-margin: 0.75em;
|
||||
|
||||
.status-body {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.status-pin {
|
||||
padding: $status-margin $status-margin 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.media-left {
|
||||
margin-right: $status-margin;
|
||||
}
|
||||
|
||||
.status-el {
|
||||
border-left-width: 0px;
|
||||
min-width: 0;
|
||||
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(--selectedPost, $fallback--lightBg);
|
||||
color: $fallback--text;
|
||||
color: var(--selectedPostText, $fallback--text);
|
||||
--lightText: var(--selectedPostLightText, $fallback--light);
|
||||
--faint: var(--selectedPostFaintText, $fallback--faint);
|
||||
--faintLink: var(--selectedPostFaintLink, $fallback--faint);
|
||||
--postLink: var(--selectedPostPostLink, $fallback--faint);
|
||||
--postFaintLink: var(--selectedPostFaintPostLink, $fallback--faint);
|
||||
--icon: var(--selectedPostIcon, $fallback--icon);
|
||||
}
|
||||
|
||||
.timeline & {
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
}
|
||||
|
||||
.media-body {
|
||||
flex: 1;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.status-usercard {
|
||||
margin-bottom: $status-margin;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
max-width: 85%;
|
||||
font-weight: bold;
|
||||
|
||||
img.emoji {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
vertical-align: middle;
|
||||
object-fit: contain
|
||||
}
|
||||
}
|
||||
|
||||
.status-favicon {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
margin-right: 0.4em;
|
||||
}
|
||||
|
||||
.media-heading {
|
||||
padding: 0;
|
||||
vertical-align: bottom;
|
||||
flex-basis: 100%;
|
||||
margin-bottom: 0.5em;
|
||||
|
||||
small {
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
.heading-name-row {
|
||||
padding: 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
line-height: 18px;
|
||||
|
||||
a {
|
||||
display: inline-block;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.name-and-account-name {
|
||||
display: flex;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
flex-shrink: 1;
|
||||
margin-right: 0.4em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.account-name {
|
||||
min-width: 1.6em;
|
||||
margin-right: 0.4em;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
flex: 1 1 0;
|
||||
}
|
||||
}
|
||||
|
||||
.heading-right {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.timeago {
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
|
||||
.heading-reply-row {
|
||||
position: relative;
|
||||
align-content: baseline;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
max-width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: stretch;
|
||||
|
||||
> .reply-to-and-accountname > a {
|
||||
overflow: hidden;
|
||||
max-width: 100%;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
|
||||
.reply-to-and-accountname {
|
||||
display: flex;
|
||||
height: 18px;
|
||||
margin-right: 0.5em;
|
||||
max-width: 100%;
|
||||
.icon-reply {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
}
|
||||
|
||||
.reply-info {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.reply-to-popover {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.reply-to {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.reply-to-text {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin: 0 0.4em 0 0.2em;
|
||||
}
|
||||
|
||||
.strikethrough {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.replies-separator {
|
||||
margin-left: 0.4em;
|
||||
}
|
||||
|
||||
.replies {
|
||||
line-height: 18px;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
& > * {
|
||||
margin-right: 0.4em;
|
||||
}
|
||||
}
|
||||
|
||||
.reply-link {
|
||||
height: 17px;
|
||||
}
|
||||
}
|
||||
|
||||
.retweet-info {
|
||||
padding: 0.4em $status-margin;
|
||||
margin: 0;
|
||||
|
||||
.avatar.still-image {
|
||||
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;
|
||||
|
||||
display: flex;
|
||||
align-content: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.user-name {
|
||||
font-weight: bold;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
img {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
vertical-align: middle;
|
||||
object-fit: contain
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
padding: 0 0.2em;
|
||||
}
|
||||
|
||||
a {
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.status-fadein {
|
||||
animation-duration: 0.4s;
|
||||
animation-name: fadein;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.status-conversation {
|
||||
border-left-style: solid;
|
||||
}
|
||||
|
||||
.status-actions {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
margin-top: $status-margin;
|
||||
|
||||
> * {
|
||||
max-width: 4em;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.button-icon.icon-reply {
|
||||
&:not(.button-icon-disabled):hover,
|
||||
&.button-icon-active {
|
||||
color: $fallback--cBlue;
|
||||
color: var(--cBlue, $fallback--cBlue);
|
||||
}
|
||||
}
|
||||
|
||||
.button-icon.icon-reply {
|
||||
&:not(.button-icon-disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.status:hover .animated.avatar {
|
||||
canvas {
|
||||
display: none;
|
||||
}
|
||||
img {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.status {
|
||||
display: flex;
|
||||
padding: $status-margin;
|
||||
&.is-retweet {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.status-conversation:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.muted {
|
||||
padding: .25em .6em;
|
||||
height: 1.2em;
|
||||
line-height: 1.2em;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
.username, .mute-thread, .mute-words {
|
||||
word-wrap: normal;
|
||||
word-break: normal;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.username, .mute-words {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.username {
|
||||
flex: 0 1 auto;
|
||||
margin-right: .2em;
|
||||
}
|
||||
|
||||
.mute-thread {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.mute-words {
|
||||
flex: 1 0 5em;
|
||||
margin-left: .2em;
|
||||
&::before {
|
||||
content: ' '
|
||||
}
|
||||
}
|
||||
|
||||
.unmute {
|
||||
flex: 0 0 auto;
|
||||
margin-left: auto;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.reply-body {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.favs-repeated-users {
|
||||
margin-top: $status-margin;
|
||||
|
||||
.stats {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
line-height: 1em;
|
||||
|
||||
.stat-count {
|
||||
margin-right: $status-margin;
|
||||
user-select: none;
|
||||
|
||||
&:hover .stat-title {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.stat-title {
|
||||
color: var(--faint, $fallback--faint);
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-weight: bolder;
|
||||
font-size: 16px;
|
||||
line-height: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-row {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
left: 0;
|
||||
background-color: var(--faint, $fallback--faint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
.status-el {
|
||||
.retweet-info {
|
||||
.avatar.still-image {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.status {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.status .avatar.still-image {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
&.avatar-compact {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
<style src="./status.scss" lang="scss"></style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<div class="status-body">
|
||||
<div class="StatusContent">
|
||||
<slot name="header" />
|
||||
<div
|
||||
v-if="status.summary_html"
|
||||
|
@ -133,7 +133,7 @@
|
|||
|
||||
$status-margin: 0.75em;
|
||||
|
||||
.status-body {
|
||||
.StatusContent {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
|
||||
|
@ -275,6 +275,7 @@ $status-margin: 0.75em;
|
|||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
height: 1.4em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -283,13 +284,4 @@ $status-margin: 0.75em;
|
|||
color: $fallback--cGreen;
|
||||
color: var(--postGreentext, $fallback--cGreen);
|
||||
}
|
||||
|
||||
.timeline :not(.panel-disabled) > {
|
||||
.status-el:last-child {
|
||||
border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;
|
||||
border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<Popover
|
||||
trigger="hover"
|
||||
popover-class="status-popover"
|
||||
popover-class="popover-default status-popover"
|
||||
:bound-to="{ x: 'container' }"
|
||||
@show="enter"
|
||||
>
|
||||
|
@ -38,7 +38,8 @@
|
|||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.status-popover {
|
||||
/* popover styles load on-demand, so we need to override */
|
||||
.status-popover.popover {
|
||||
font-size: 1rem;
|
||||
min-width: 15em;
|
||||
max-width: 95%;
|
||||
|
@ -52,7 +53,8 @@
|
|||
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
|
||||
box-shadow: var(--popupShadow);
|
||||
|
||||
.status-el.status-el {
|
||||
/* TODO cleanup this */
|
||||
.Status.Status {
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,48 +30,9 @@
|
|||
position: relative;
|
||||
line-height: 0;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:hover canvas {
|
||||
display: none;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
&.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;
|
||||
|
@ -81,6 +42,45 @@
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
visibility: var(--still-image-canvas, visible);
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
&.animated {
|
||||
&::before {
|
||||
content: 'gif';
|
||||
position: absolute;
|
||||
line-height: 10px;
|
||||
font-size: 10px;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
background: rgba(127, 127, 127, 0.5);
|
||||
color: #fff;
|
||||
display: block;
|
||||
padding: 2px 4px;
|
||||
border-radius: $fallback--tooltipRadius;
|
||||
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
|
||||
z-index: 2;
|
||||
visibility: var(--still-image-label-visibility, visible);
|
||||
}
|
||||
|
||||
&:hover canvas {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover::before,
|
||||
img {
|
||||
visibility: var(--still-image-img, hidden);
|
||||
}
|
||||
|
||||
&:hover img {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Vue from 'vue'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
import './tab_switcher.scss'
|
||||
|
||||
|
@ -44,7 +45,13 @@ export default Vue.component('tab-switcher', {
|
|||
} else {
|
||||
return this.active
|
||||
}
|
||||
}
|
||||
},
|
||||
settingsModalVisible () {
|
||||
return this.settingsModalState === 'visible'
|
||||
},
|
||||
...mapState({
|
||||
settingsModalState: state => state.interface.settingsModalState
|
||||
})
|
||||
},
|
||||
beforeUpdate () {
|
||||
const currentSlot = this.$slots.default[this.active]
|
||||
|
@ -134,7 +141,7 @@ export default Vue.component('tab-switcher', {
|
|||
<div class="tabs">
|
||||
{tabs}
|
||||
</div>
|
||||
<div ref="contents" class={'contents' + (this.scrollableTabs ? ' scrollable-tabs' : '')}>
|
||||
<div ref="contents" class={'contents' + (this.scrollableTabs ? ' scrollable-tabs' : '')} v-body-scroll-lock={this.settingsModalVisible}>
|
||||
{contents}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import Status from '../status/status.vue'
|
||||
import timelineFetcher from '../../services/timeline_fetcher/timeline_fetcher.service.js'
|
||||
import Conversation from '../conversation/conversation.vue'
|
||||
import TimelineMenu from '../timeline_menu/timeline_menu.vue'
|
||||
import { throttle, keyBy } from 'lodash'
|
||||
|
||||
export const getExcludedStatusIdsByPinning = (statuses, pinnedStatusIds) => {
|
||||
|
@ -35,6 +36,11 @@ const Timeline = {
|
|||
bottomedOut: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Status,
|
||||
Conversation,
|
||||
TimelineMenu
|
||||
},
|
||||
computed: {
|
||||
timelineError () {
|
||||
return this.$store.state.statuses.error
|
||||
|
@ -74,10 +80,6 @@ const Timeline = {
|
|||
return keyBy(this.pinnedStatusIds)
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Status,
|
||||
Conversation
|
||||
},
|
||||
created () {
|
||||
const store = this.$store
|
||||
const credentials = store.state.users.currentUser.credentials
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
<template>
|
||||
<div :class="classes.root">
|
||||
<div :class="[classes.root, 'timeline']">
|
||||
<div :class="classes.header">
|
||||
<div class="title">
|
||||
{{ title }}
|
||||
</div>
|
||||
<TimelineMenu v-if="!embedded" />
|
||||
<div
|
||||
v-if="timelineError"
|
||||
class="loadmore-error alert error"
|
||||
|
@ -106,4 +104,16 @@
|
|||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-heading {
|
||||
max-width: 100%;
|
||||
flex-wrap: nowrap;
|
||||
.loadmore-button {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.loadmore-text {
|
||||
flex-shrink: 0;
|
||||
line-height: 1em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
63
src/components/timeline_menu/timeline_menu.js
Normal file
63
src/components/timeline_menu/timeline_menu.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
import Popover from '../popover/popover.vue'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
// Route -> i18n key mapping, exported andnot in the computed
|
||||
// because nav panel benefits from the same information.
|
||||
export const timelineNames = () => {
|
||||
return {
|
||||
'friends': 'nav.timeline',
|
||||
'bookmarks': 'nav.bookmarks',
|
||||
'dms': 'nav.dms',
|
||||
'public-timeline': 'nav.public_tl',
|
||||
'public-external-timeline': 'nav.twkn',
|
||||
'tag-timeline': 'tag'
|
||||
}
|
||||
}
|
||||
|
||||
const TimelineMenu = {
|
||||
components: {
|
||||
Popover
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
isOpen: false
|
||||
}
|
||||
},
|
||||
created () {
|
||||
if (this.currentUser && this.currentUser.locked) {
|
||||
this.$store.dispatch('startFetchingFollowRequests')
|
||||
}
|
||||
if (timelineNames()[this.$route.name]) {
|
||||
this.$store.dispatch('setLastTimeline', this.$route.name)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openMenu () {
|
||||
// $nextTick is too fast, animation won't play back but
|
||||
// instead starts in fully open position. Low values
|
||||
// like 1-5 work on fast machines but not on mobile, 25
|
||||
// seems like a good compromise that plays without significant
|
||||
// added lag.
|
||||
setTimeout(() => {
|
||||
this.isOpen = true
|
||||
}, 25)
|
||||
},
|
||||
timelineName () {
|
||||
const route = this.$route.name
|
||||
if (route === 'tag-timeline') {
|
||||
return '#' + this.$route.params.tag
|
||||
}
|
||||
const i18nkey = timelineNames()[this.$route.name]
|
||||
return i18nkey ? this.$t(i18nkey) : route
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
currentUser: state => state.users.currentUser,
|
||||
privateMode: state => state.instance.private,
|
||||
federating: state => state.instance.federating
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default TimelineMenu
|
180
src/components/timeline_menu/timeline_menu.vue
Normal file
180
src/components/timeline_menu/timeline_menu.vue
Normal file
|
@ -0,0 +1,180 @@
|
|||
<template>
|
||||
<Popover
|
||||
trigger="click"
|
||||
class="timeline-menu"
|
||||
:class="{ 'open': isOpen }"
|
||||
:margin="{ left: -15, right: -200 }"
|
||||
:bound-to="{ x: 'container' }"
|
||||
popover-class="timeline-menu-popover-wrap"
|
||||
@show="openMenu"
|
||||
@close="() => isOpen = false"
|
||||
>
|
||||
<div
|
||||
slot="content"
|
||||
class="timeline-menu-popover panel panel-default"
|
||||
>
|
||||
<ul>
|
||||
<li v-if="currentUser">
|
||||
<router-link :to="{ name: 'friends' }">
|
||||
<i class="button-icon icon-home-2" />{{ $t("nav.timeline") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li v-if="currentUser">
|
||||
<router-link :to="{ name: 'bookmarks'}">
|
||||
<i class="button-icon icon-bookmark" />{{ $t("nav.bookmarks") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li v-if="currentUser">
|
||||
<router-link :to="{ name: 'dms', params: { username: currentUser.screen_name } }">
|
||||
<i class="button-icon icon-mail-alt" />{{ $t("nav.dms") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li v-if="currentUser || !privateMode">
|
||||
<router-link :to="{ name: 'public-timeline' }">
|
||||
<i class="button-icon icon-users" />{{ $t("nav.public_tl") }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li v-if="federating && (currentUser || !privateMode)">
|
||||
<router-link :to="{ name: 'public-external-timeline' }">
|
||||
<i class="button-icon icon-globe" />{{ $t("nav.twkn") }}
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div
|
||||
slot="trigger"
|
||||
class="title timeline-menu-title"
|
||||
>
|
||||
<span>{{ timelineName() }}</span>
|
||||
<i class="icon-down-open" />
|
||||
</div>
|
||||
</Popover>
|
||||
</template>
|
||||
|
||||
<script src="./timeline_menu.js" ></script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.timeline-menu {
|
||||
flex-shrink: 1;
|
||||
margin-right: auto;
|
||||
min-width: 0;
|
||||
width: 24rem;
|
||||
.timeline-menu-popover-wrap {
|
||||
overflow: hidden;
|
||||
// Match panel heading padding to line up menu with bottom of heading
|
||||
margin-top: 0.6rem;
|
||||
padding: 0 15px 15px 15px;
|
||||
}
|
||||
.timeline-menu-popover {
|
||||
width: 24rem;
|
||||
max-width: 100vw;
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
border-top-right-radius: 0;
|
||||
border-top-left-radius: 0;
|
||||
transform: translateY(-100%);
|
||||
transition: transform 100ms;
|
||||
}
|
||||
.panel::after {
|
||||
border-top-right-radius: 0;
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
&.open .timeline-menu-popover {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.timeline-menu-title {
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
user-select: none;
|
||||
width: 100%;
|
||||
|
||||
span {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
i {
|
||||
margin-left: 0.6em;
|
||||
flex-shrink: 0;
|
||||
font-size: 1rem;
|
||||
transition: transform 100ms;
|
||||
}
|
||||
}
|
||||
|
||||
&.open .timeline-menu-title i {
|
||||
color: $fallback--text;
|
||||
color: var(--panelText, $fallback--text);
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.panel {
|
||||
box-shadow: var(--popoverShadow);
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
border-bottom: 1px solid;
|
||||
border-color: $fallback--border;
|
||||
border-color: var(--border, $fallback--border);
|
||||
padding: 0;
|
||||
|
||||
&: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);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
i {
|
||||
margin: 0 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
display: block;
|
||||
padding: 0.6em 0;
|
||||
|
||||
&:hover {
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--selectedMenu, $fallback--lightBg);
|
||||
color: $fallback--link;
|
||||
color: var(--selectedMenuText, $fallback--link);
|
||||
--faint: var(--selectedMenuFaintText, $fallback--faint);
|
||||
--faintLink: var(--selectedMenuFaintLink, $fallback--faint);
|
||||
--lightText: var(--selectedMenuLightText, $fallback--lightText);
|
||||
--icon: var(--selectedMenuIcon, $fallback--icon);
|
||||
}
|
||||
|
||||
&.router-link-active {
|
||||
font-weight: bolder;
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--selectedMenu, $fallback--lightBg);
|
||||
color: $fallback--text;
|
||||
color: var(--selectedMenuText, $fallback--text);
|
||||
--faint: var(--selectedMenuFaintText, $fallback--faint);
|
||||
--faintLink: var(--selectedMenuFaintLink, $fallback--faint);
|
||||
--lightText: var(--selectedMenuLightText, $fallback--lightText);
|
||||
--icon: var(--selectedMenuIcon, $fallback--icon);
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<StillImage
|
||||
class="avatar"
|
||||
class="Avatar"
|
||||
:alt="user.screen_name"
|
||||
:title="user.screen_name"
|
||||
:src="imgSrc(user.profile_image_url_original)"
|
||||
|
@ -13,7 +13,9 @@
|
|||
<style lang="scss">
|
||||
@import '../../_variables.scss';
|
||||
|
||||
.avatar.still-image {
|
||||
.Avatar {
|
||||
--still-image-label-visibility: hidden;
|
||||
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
box-shadow: var(--avatarStatusShadow);
|
||||
|
|
|
@ -354,7 +354,7 @@
|
|||
align-items: flex-start;
|
||||
max-height: 56px;
|
||||
|
||||
.avatar {
|
||||
.Avatar {
|
||||
flex: 1 0 100%;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
|
@ -364,13 +364,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
&:hover .animated.avatar {
|
||||
canvas {
|
||||
display: none;
|
||||
}
|
||||
img {
|
||||
visibility: visible;
|
||||
}
|
||||
&:hover .Avatar {
|
||||
--still-image-img: visible;
|
||||
--still-image-canvas: hidden;
|
||||
}
|
||||
|
||||
&-avatar-link {
|
||||
|
|
|
@ -20,13 +20,14 @@
|
|||
:key="index"
|
||||
class="user-profile-field"
|
||||
>
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<dt
|
||||
:title="user.fields_text[index].name"
|
||||
class="user-profile-field-name"
|
||||
@click.prevent="linkClicked"
|
||||
v-html="field.name"
|
||||
/>
|
||||
>
|
||||
{{ field.name }}
|
||||
</dt>
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<dd
|
||||
:title="user.fields_text[index].value"
|
||||
class="user-profile-field-value"
|
||||
|
|
|
@ -146,7 +146,8 @@
|
|||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
> .status-el {
|
||||
/* TODO cleanup this */
|
||||
> .Status {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
"dms": "Direktnachrichten",
|
||||
"public_tl": "Öffentliche Zeitleiste",
|
||||
"timeline": "Zeitleiste",
|
||||
"twkn": "Das gesamte bekannte Netzwerk",
|
||||
"twkn": "Bekannte Netzwerk",
|
||||
"user_search": "Benutzersuche",
|
||||
"search": "Suche",
|
||||
"preferences": "Voreinstellungen",
|
||||
|
|
|
@ -120,12 +120,13 @@
|
|||
"dms": "Direct Messages",
|
||||
"public_tl": "Public Timeline",
|
||||
"timeline": "Timeline",
|
||||
"twkn": "The Whole Known Network",
|
||||
"twkn": "Known Network",
|
||||
"bookmarks": "Bookmarks",
|
||||
"user_search": "User Search",
|
||||
"search": "Search",
|
||||
"who_to_follow": "Who to follow",
|
||||
"preferences": "Preferences",
|
||||
"timelines": "Timelines",
|
||||
"chats": "Chats"
|
||||
},
|
||||
"notifications": {
|
||||
|
|
255
src/i18n/eo.json
255
src/i18n/eo.json
|
@ -5,7 +5,7 @@
|
|||
"features_panel": {
|
||||
"chat": "Babilejo",
|
||||
"gopher": "Gopher",
|
||||
"media_proxy": "Aŭdvidaĵa prokurilo",
|
||||
"media_proxy": "Vidaŭdaĵa prokurilo",
|
||||
"scope_options": "Agordoj de amplekso",
|
||||
"text_limit": "Limo de teksto",
|
||||
"title": "Funkcioj",
|
||||
|
@ -79,7 +79,8 @@
|
|||
"chats": "Babiloj",
|
||||
"search": "Serĉi",
|
||||
"interactions": "Interagoj",
|
||||
"administration": "Administrado"
|
||||
"administration": "Administrado",
|
||||
"bookmarks": "Legosignoj"
|
||||
},
|
||||
"notifications": {
|
||||
"broken_favorite": "Nekonata stato, serĉante ĝin…",
|
||||
|
@ -278,7 +279,7 @@
|
|||
"true": "jes"
|
||||
},
|
||||
"notifications": "Sciigoj",
|
||||
"enable_web_push_notifications": "Ŝalti retajn puŝajn sciigojn",
|
||||
"enable_web_push_notifications": "Ŝalti retajn pasivajn sciigojn",
|
||||
"style": {
|
||||
"switcher": {
|
||||
"keep_color": "Konservi kolorojn",
|
||||
|
@ -286,10 +287,22 @@
|
|||
"keep_opacity": "Konservi maltravideblecon",
|
||||
"keep_roundness": "Konservi rondecon",
|
||||
"keep_fonts": "Konservi tiparojn",
|
||||
"save_load_hint": "Elektebloj de \"konservi\" konservas la nuntempajn agordojn dum elektado aŭ enlegado de haŭtoj. Ĝi ankaŭ konservas tiujn agordojn dum elportado de haŭto. Kun ĉiuj markbutonoj nemarkitaj, elporto de la haŭto ĉion konservos.",
|
||||
"save_load_hint": "Elektebloj de «konservi» konservas la nuntempajn agordojn dum elektado aŭ enlegado de haŭtoj. Ĝi ankaŭ konservas tiujn agordojn dum elportado de haŭto. Kun ĉiuj markbutonoj nemarkitaj, elporto de la haŭto ĉion konservos.",
|
||||
"reset": "Restarigi",
|
||||
"clear_all": "Vakigi ĉion",
|
||||
"clear_opacity": "Vakigi maltravideblecon"
|
||||
"clear_opacity": "Vakigi maltravideblecon",
|
||||
"help": {
|
||||
"fe_downgraded": "Versio de PleromaFE reen iris.",
|
||||
"fe_upgraded": "La motoro de haŭtoj de PleromaFE ĝisdatiĝis post ĝisdatigo de la versio.",
|
||||
"older_version_imported": "La enportita dosiero estis farita per pli malnova versio de PleromaFE.",
|
||||
"future_version_imported": "La enportita dosiero estis farita per pli nova versio de PleromaFE.",
|
||||
"v2_imported": "La dosiero, kiun vi enportis, estis farita por malnova versio de PleromaFE. Ni provas maksimumigi interkonformecon, sed tamen eble montriĝos misoj.",
|
||||
"upgraded_from_v2": "PleromaFE estis ĝisdatigita; la haŭto eble aspektos malsame ol kiel vi ĝin memoras."
|
||||
},
|
||||
"use_source": "Nova versio",
|
||||
"use_snapshot": "Malnova versio",
|
||||
"keep_as_is": "Teni senŝanĝa",
|
||||
"load_theme": "Enlegi haŭton"
|
||||
},
|
||||
"common": {
|
||||
"color": "Koloro",
|
||||
|
@ -297,7 +310,7 @@
|
|||
"contrast": {
|
||||
"hint": "Proporcio de kontrasto estas {ratio}, ĝi {level} {context}",
|
||||
"level": {
|
||||
"aa": "plenumas la gvidilon je nivelo AA (malpleja)",
|
||||
"aa": "plenumas la gvidilon je nivelo AA (minimuma)",
|
||||
"aaa": "plenumas la gvidilon je nivela AAA (rekomendita)",
|
||||
"bad": "plenumas neniujn faciluzajn gvidilojn"
|
||||
},
|
||||
|
@ -310,21 +323,39 @@
|
|||
"common_colors": {
|
||||
"_tab_label": "Komunaj",
|
||||
"main": "Komunaj koloroj",
|
||||
"foreground_hint": "Vidu langeton \"Specialaj\" por pli detalaj agordoj",
|
||||
"foreground_hint": "Vidu langeton «Specialaj» por pli detalaj agordoj",
|
||||
"rgbo": "Bildsimboloj, emfazoj, insignoj"
|
||||
},
|
||||
"advanced_colors": {
|
||||
"_tab_label": "Specialaj",
|
||||
"alert": "Averta fono",
|
||||
"alert": "Fono de averto",
|
||||
"alert_error": "Eraro",
|
||||
"badge": "Insigna fono",
|
||||
"badge": "Fono de insigno",
|
||||
"badge_notification": "Sciigo",
|
||||
"panel_header": "Kapo de breto",
|
||||
"top_bar": "Supra breto",
|
||||
"borders": "Limoj",
|
||||
"buttons": "Butonoj",
|
||||
"inputs": "Enigaj kampoj",
|
||||
"faint_text": "Malvigla teksto"
|
||||
"faint_text": "Malvigla teksto",
|
||||
"chat": {
|
||||
"border": "Limo",
|
||||
"outgoing": "Eliraj",
|
||||
"incoming": "Envenaj"
|
||||
},
|
||||
"tabs": "Langetoj",
|
||||
"disabled": "Malŝaltita",
|
||||
"selectedMenu": "Elektita menuero",
|
||||
"selectedPost": "Elektita afiŝo",
|
||||
"pressed": "Premita",
|
||||
"highlight": "Emfazitaj eroj",
|
||||
"icons": "Bildsimboloj",
|
||||
"poll": "Grafo de enketo",
|
||||
"underlay": "Subtavolo",
|
||||
"popover": "Ŝpruchelpiloj, menuoj",
|
||||
"post": "Afiŝoj/Priskriboj de uzantoj",
|
||||
"alert_neutral": "Neŭtrala",
|
||||
"alert_warning": "Averto"
|
||||
},
|
||||
"radii": {
|
||||
"_tab_label": "Rondeco"
|
||||
|
@ -339,7 +370,7 @@
|
|||
"inset": "Internigo",
|
||||
"hint": "Por ombroj vi ankaŭ povas uzi --variable kiel koloran valoron, por uzi variantojn de CSS3. Bonvolu rimarki, ke tiuokaze agordoj de maltravidebleco ne funkcios.",
|
||||
"filter_hint": {
|
||||
"always_drop_shadow": "Averto: ĉi tiu ombro ĉiam uzas {0} kiam la foliumilo ĝin subtenas.",
|
||||
"always_drop_shadow": "Averto: ĉi tiu ombro ĉiam uzas {0} kiam la foliumilo tion subtenas.",
|
||||
"drop_shadow_syntax": "{0} ne subtenas parametron {1} kaj ŝlosilvorton {2}.",
|
||||
"avatar_inset": "Bonvolu rimarki, ke agordi ambaŭ internajn kaj eksterajn ombrojn por profilbildoj povas redoni neatenditajn rezultojn ĉe profilbildoj travideblaj.",
|
||||
"spread_zero": "Ombroj kun vastigo > 0 aperos kvazaŭ ĝi estus fakte nulo",
|
||||
|
@ -355,13 +386,13 @@
|
|||
"button": "Butono",
|
||||
"buttonHover": "Butono (je ŝvebo)",
|
||||
"buttonPressed": "Butono (premita)",
|
||||
"buttonPressedHover": "Butono (premita je ŝvebo)",
|
||||
"buttonPressedHover": "Butono (premita kaj je ŝvebo)",
|
||||
"input": "Eniga kampo"
|
||||
}
|
||||
},
|
||||
"fonts": {
|
||||
"_tab_label": "Tiparoj",
|
||||
"help": "Elektu tiparon uzotan por eroj de la fasado. Por \"propra\" vi devas enigi la precizan nomon de tiparo tiel, kiel ĝi aperas en la sistemo.",
|
||||
"help": "Elektu tiparon uzotan por eroj de la fasado. Por «propra» vi devas enigi la precizan nomon de tiparo tiel, kiel ĝi aperas en la sistemo.",
|
||||
"components": {
|
||||
"interface": "Fasado",
|
||||
"input": "Enigaj kampoj",
|
||||
|
@ -416,7 +447,8 @@
|
|||
"recovery_codes": "Rehavaj kodoj.",
|
||||
"warning_of_generate_new_codes": "Kiam vi estigos novajn rehavajn kodojn, viaj malnovaj ne plu funkcios.",
|
||||
"generate_new_recovery_codes": "Estigi novajn rehavajn kodojn",
|
||||
"title": "Duobla aŭtentikigo"
|
||||
"title": "Duobla aŭtentikigo",
|
||||
"otp": "OTP"
|
||||
},
|
||||
"enter_current_password_to_confirm": "Enigu vian pasvorton por konfirmi vian identecon",
|
||||
"security": "Sekureco",
|
||||
|
@ -450,64 +482,109 @@
|
|||
"hide_muted_posts": "Kaŝi afiŝojn de silentigitaj uzantoj",
|
||||
"emoji_reactions_on_timeline": "Montri bildosignajn reagojn en la tempolinio",
|
||||
"pad_emoji": "Meti spacetojn ĉirkaŭ bildosigno post ties elekto",
|
||||
"domain_mutes": "Retnomoj"
|
||||
"domain_mutes": "Retnomoj",
|
||||
"notification_blocks": "Blokinte uzanton vi malabonos ĝin kaj haltigos ĉiujn sciigojn.",
|
||||
"notification_mutes": "Por ne plu ricevi sciigojn de certa uzanto, silentigu.",
|
||||
"notification_setting_hide_notification_contents": "Kaŝi la sendinton kaj la enhavojn de pasivaj sciigoj",
|
||||
"notification_setting_privacy": "Privateco",
|
||||
"notification_setting_block_from_strangers": "Bloki sciigojn de uzantoj, kiujn vi ne abonas",
|
||||
"notification_setting_filters": "Filtriloj",
|
||||
"greentext": "Memecitaĵoj",
|
||||
"version": {
|
||||
"frontend_version": "Versio de fasado",
|
||||
"backend_version": "Versio de internaĵo",
|
||||
"title": "Versio"
|
||||
},
|
||||
"accent": "Emfazo"
|
||||
},
|
||||
"timeline": {
|
||||
"collapse": "Maletendi",
|
||||
"conversation": "Interparolo",
|
||||
"error_fetching": "Eraro dum ĝisdatigo",
|
||||
"error_fetching": "Eraris ĝisdatigo",
|
||||
"load_older": "Montri pli malnovajn statojn",
|
||||
"no_retweet_hint": "Afiŝo estas markita kiel rekta aŭ nur por abonantoj, kaj ne eblas ĝin ripeti",
|
||||
"repeated": "ripetita",
|
||||
"show_new": "Montri novajn",
|
||||
"up_to_date": "Ĝisdata",
|
||||
"no_more_statuses": "Neniuj pliaj statoj",
|
||||
"no_statuses": "Neniuj statoj"
|
||||
"no_statuses": "Neniuj statoj",
|
||||
"reload": "Enlegi ree"
|
||||
},
|
||||
"user_card": {
|
||||
"approve": "Aprobi",
|
||||
"block": "Bari",
|
||||
"blocked": "Barita!",
|
||||
"block": "Bloki",
|
||||
"blocked": "Blokita!",
|
||||
"deny": "Rifuzi",
|
||||
"favorites": "Ŝatataj",
|
||||
"follow": "Aboni",
|
||||
"follow_sent": "Peto sendiĝis!",
|
||||
"follow_progress": "Petanta…",
|
||||
"follow_again": "Ĉu sendi peton denove?",
|
||||
"follow_progress": "Petante…",
|
||||
"follow_again": "Ĉu sendi peton ree?",
|
||||
"follow_unfollow": "Malaboni",
|
||||
"followees": "Abonatoj",
|
||||
"followers": "Abonantoj",
|
||||
"following": "Abonanta!",
|
||||
"following": "Abonata!",
|
||||
"follows_you": "Abonas vin!",
|
||||
"its_you": "Tio estas vi!",
|
||||
"media": "Aŭdvidaĵoj",
|
||||
"media": "Vidaŭdaĵoj",
|
||||
"mute": "Silentigi",
|
||||
"muted": "Silentigitaj",
|
||||
"muted": "Silentigita",
|
||||
"per_day": "tage",
|
||||
"remote_follow": "Fore aboni",
|
||||
"statuses": "Statoj",
|
||||
"unblock": "Malbari",
|
||||
"unblock_progress": "Malbaranta…",
|
||||
"block_progress": "Baranta…",
|
||||
"unblock": "Malbloki",
|
||||
"unblock_progress": "Malblokante…",
|
||||
"block_progress": "Blokante…",
|
||||
"unmute": "Malsilentigi",
|
||||
"unmute_progress": "Malsilentiganta…",
|
||||
"mute_progress": "Silentiganta…"
|
||||
"unmute_progress": "Malsilentigante…",
|
||||
"mute_progress": "Silentigante…",
|
||||
"report": "Raporti",
|
||||
"message": "Mesaĝo",
|
||||
"mention": "Mencio",
|
||||
"hidden": "Kaŝita",
|
||||
"admin_menu": {
|
||||
"delete_user_confirmation": "Ĉu vi tute certas? Ĉi tiu ago ne estas malfarebla.",
|
||||
"delete_user": "Forigi uzanton",
|
||||
"quarantine": "Malpermesi federadon de afiŝoj de uzanto",
|
||||
"disable_any_subscription": "Malpermesi ĉian abonadon al uzanto",
|
||||
"disable_remote_subscription": "Malpermesi abonadon al uzanto el foraj nodoj",
|
||||
"sandbox": "Devigi afiŝojn esti nur por abonantoj",
|
||||
"force_unlisted": "Devigi afiŝojn nelistiĝi",
|
||||
"strip_media": "Forigi vidaŭdaĵojn de afiŝoj",
|
||||
"force_nsfw": "Marki ĉiujn afiŝojn konsternaj",
|
||||
"delete_account": "Forigi konton",
|
||||
"deactivate_account": "Malaktivigi konton",
|
||||
"activate_account": "Aktivigi konton",
|
||||
"revoke_moderator": "Malnomumi reguligiston",
|
||||
"grant_moderator": "Nomumi reguligiston",
|
||||
"revoke_admin": "Malnomumi administranton",
|
||||
"grant_admin": "Nomumi administranton",
|
||||
"moderation": "Reguligado"
|
||||
},
|
||||
"show_repeats": "Montri ripetojn",
|
||||
"hide_repeats": "Kaŝi ripetojn",
|
||||
"unsubscribe": "Ne ricevi sciigojn",
|
||||
"subscribe": "Ricevi sciigojn"
|
||||
},
|
||||
"user_profile": {
|
||||
"timeline_title": "Uzanta tempolinio",
|
||||
"timeline_title": "Historio de uzanto",
|
||||
"profile_does_not_exist": "Pardonu, ĉi tiu profilo ne ekzistas.",
|
||||
"profile_loading_error": "Pardonu, eraro okazis dum enlegado de ĉi tiu profilo."
|
||||
"profile_loading_error": "Pardonu, eraris enlego de ĉi tiu profilo."
|
||||
},
|
||||
"who_to_follow": {
|
||||
"more": "Pli",
|
||||
"who_to_follow": "Kiun aboni"
|
||||
},
|
||||
"tool_tip": {
|
||||
"media_upload": "Alŝuti aŭdvidaĵon",
|
||||
"media_upload": "Alŝuti vidaŭdaĵon",
|
||||
"repeat": "Ripeti",
|
||||
"reply": "Respondi",
|
||||
"favorite": "Ŝati",
|
||||
"user_settings": "Agordoj de uzanto"
|
||||
"user_settings": "Agordoj de uzanto",
|
||||
"bookmark": "Legosigno",
|
||||
"reject_follow_request": "Rifuzi abonpeton",
|
||||
"accept_follow_request": "Akcepti abonpeton",
|
||||
"add_reaction": "Aldoni reagon"
|
||||
},
|
||||
"upload": {
|
||||
"error": {
|
||||
|
@ -580,7 +657,7 @@
|
|||
"accept": "Akcepti",
|
||||
"simple_policies": "Specialaj politikoj de la nodo"
|
||||
},
|
||||
"mrf_policies": "Ŝaltis politikon de MRF",
|
||||
"mrf_policies": "Ŝaltis politikon de Mesaĝa ŝanĝilaro (MRF)",
|
||||
"keyword": {
|
||||
"is_replaced_by": "→",
|
||||
"replace": "Anstataŭigi",
|
||||
|
@ -588,7 +665,8 @@
|
|||
"ftl_removal": "Forigo de la historio de «La tuta konata reto»",
|
||||
"keyword_policies": "Politiko pri ŝlosilvortoj"
|
||||
},
|
||||
"federation": "Federado"
|
||||
"federation": "Federado",
|
||||
"mrf_policies_desc": "Politikoj de Mesaĝa ŝanĝilaro (MRF) efikas sur federa konduto de la nodo. La sekvaj politikoj estas ŝaltitaj:"
|
||||
}
|
||||
},
|
||||
"selectable_list": {
|
||||
|
@ -607,5 +685,112 @@
|
|||
},
|
||||
"errors": {
|
||||
"storage_unavailable": "Pleroma ne povis aliri deponejon de la foliumilo. Via saluto kaj viaj lokaj agordoj ne estos konservitaj, kaj vi eble renkontos neatenditajn problemojn. Provu permesi kuketojn."
|
||||
},
|
||||
"status": {
|
||||
"hide_content": "Kaŝi enhavon",
|
||||
"show_content": "Montri enhavon",
|
||||
"hide_full_subject": "Kaŝi plenan temon",
|
||||
"show_full_subject": "Montri plenan temon",
|
||||
"thread_muted_and_words": ", enhavas vortojn:",
|
||||
"thread_muted": "Fadeno silentigita",
|
||||
"copy_link": "Kopii ligilon al stato",
|
||||
"status_unavailable": "Stato ne estas disponebla",
|
||||
"unmute_conversation": "Malsilentigi interparolon",
|
||||
"mute_conversation": "Silentigi interparolon",
|
||||
"replies_list": "Respondoj:",
|
||||
"reply_to": "Responde al",
|
||||
"delete_confirm": "Ĉu vi certe volas forigi ĉi tiun staton?",
|
||||
"unbookmark": "Senlegosigni",
|
||||
"bookmark": "Legosigni",
|
||||
"pinned": "Fiksita",
|
||||
"unpin": "Malfiksi de profilo",
|
||||
"pin": "Fiksi al profilo",
|
||||
"delete": "Forigi staton",
|
||||
"repeats": "Ripetoj",
|
||||
"favorites": "Ŝatataj"
|
||||
},
|
||||
"time": {
|
||||
"years_short": "{0}j",
|
||||
"year_short": "{0}j",
|
||||
"years": "{0} jaroj",
|
||||
"year": "{0} jaro",
|
||||
"weeks_short": "{0}s",
|
||||
"week_short": "{0}s",
|
||||
"weeks": "{0} semajnoj",
|
||||
"week": "{0} semajno",
|
||||
"seconds_short": "{0}s",
|
||||
"second_short": "{0}s",
|
||||
"seconds": "{0} sekundoj",
|
||||
"second": "{0} sekundo",
|
||||
"now_short": "nun",
|
||||
"now": "ĵus",
|
||||
"months_short": "{0}m",
|
||||
"month_short": "{0}m",
|
||||
"months": "{0} monatoj",
|
||||
"month": "{0} monato",
|
||||
"minutes_short": "{0}m",
|
||||
"minute_short": "{0}m",
|
||||
"minutes": "{0} minutoj",
|
||||
"minute": "{0} minuto",
|
||||
"in_past": "antaŭ {0}",
|
||||
"in_future": "post {0}",
|
||||
"hours_short": "{0}h",
|
||||
"hour_short": "{0}h",
|
||||
"hours": "{0} horoj",
|
||||
"hour": "{0} horo",
|
||||
"days_short": "{0}t",
|
||||
"day_short": "{0}t",
|
||||
"days": "{0} tagoj",
|
||||
"day": "{0} tago"
|
||||
},
|
||||
"search": {
|
||||
"people": "Personoj",
|
||||
"no_results": "Neniuj rezultoj",
|
||||
"people_talking": "{count} personoj parolas",
|
||||
"person_talking": "{count} persono parolas",
|
||||
"hashtags": "Kradvortoj"
|
||||
},
|
||||
"display_date": {
|
||||
"today": "Hodiaŭ"
|
||||
},
|
||||
"file_type": {
|
||||
"file": "Dosiero",
|
||||
"image": "Bildo",
|
||||
"video": "Filmo",
|
||||
"audio": "Sono"
|
||||
},
|
||||
"chats": {
|
||||
"empty_chat_list_placeholder": "Vi ankoraŭ havas neniun babilon. Komencu novan babilon!",
|
||||
"error_sending_message": "Io misokazis dum sendado de la mesaĝo.",
|
||||
"error_loading_chat": "Io misokazis dum enlego de la babilo.",
|
||||
"delete_confirm": "Ĉu vi certe volas forigi ĉi tiun mesaĝon?",
|
||||
"more": "Pli",
|
||||
"empty_message_error": "Ne povas sendi malplenan mesaĝon",
|
||||
"new": "Nova babilo",
|
||||
"chats": "Babiloj",
|
||||
"delete": "Forigi",
|
||||
"you": "Vi:"
|
||||
},
|
||||
"password_reset": {
|
||||
"password_reset_required_but_mailer_is_disabled": "Vi devas restarigi vian pasvorton, sed restarigado de pasvortoj estas malŝaltita. Bonvolu kontakti la administranton de via nodo.",
|
||||
"password_reset_required": "Vi devas restarigi vian pasvorton por saluti.",
|
||||
"password_reset_disabled": "Restarigado de pasvortoj estas malŝaltita. Bonvolu kontakti la administranton de via nodo.",
|
||||
"too_many_requests": "Vi atingis la limon de provoj, reprovu pli poste.",
|
||||
"not_found": "Ni ne trovis tiun retpoŝtadreson aŭ uzantonomon.",
|
||||
"return_home": "Reiri al la hejmpaĝo",
|
||||
"check_email": "Kontrolu vian retpoŝton pro ligilo por restarigi vian pasvorton.",
|
||||
"placeholder": "Via retpoŝtadreso aŭ uzantonomo",
|
||||
"instruction": "Enigu vian retpoŝtadreson aŭ uzantonomon. Ni sendos al vi ligilon por restarigi vian pasvorton.",
|
||||
"password_reset": "Restarigi pasvorton",
|
||||
"forgot_password": "Ĉu vi forgesis pasvorton?"
|
||||
},
|
||||
"user_reporting": {
|
||||
"generic_error": "Eraris traktado de via peto.",
|
||||
"submit": "Sendi",
|
||||
"forward_to": "Plusendi al {0}",
|
||||
"forward_description": "La konto venas de alia servilo. Ĉu kopio de la raporto sendiĝu ankaŭ tien?",
|
||||
"additional_comments": "Aldonaj komentoj",
|
||||
"add_comment_description": "Ĉi tiu raporto sendiĝos al reguligistoj de via nodo. Vi povas komprenigi kial vi raportas ĉi tiun konton sube:",
|
||||
"title": "Raportante {0}"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
"dms": "Yksityisviestit",
|
||||
"public_tl": "Julkinen Aikajana",
|
||||
"timeline": "Aikajana",
|
||||
"twkn": "Koko Tunnettu Verkosto",
|
||||
"twkn": "Tunnettu Verkosto",
|
||||
"user_search": "Käyttäjähaku",
|
||||
"who_to_follow": "Seurausehdotukset",
|
||||
"preferences": "Asetukset",
|
||||
|
|
|
@ -36,7 +36,8 @@
|
|||
"who_to_follow": "Chi seguire",
|
||||
"preferences": "Preferenze",
|
||||
"bookmarks": "Segnalibri",
|
||||
"chats": "Conversazioni"
|
||||
"chats": "Conversazioni",
|
||||
"timelines": "Sequenze"
|
||||
},
|
||||
"notifications": {
|
||||
"followed_you": "ti segue",
|
||||
|
@ -805,5 +806,8 @@
|
|||
"delete": "Elimina",
|
||||
"message_user": "Contatta {nickname}",
|
||||
"you": "Tu:"
|
||||
},
|
||||
"shoutbox": {
|
||||
"title": "Graffiti"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,7 +196,8 @@
|
|||
"unlisted": "Niewidoczny – Nie umieszczaj na publicznych osiach czasu"
|
||||
},
|
||||
"preview_empty": "Pusty",
|
||||
"preview": "Podgląd"
|
||||
"preview": "Podgląd",
|
||||
"empty_status_error": "Nie można wysłać pustego wpisu bez plików"
|
||||
},
|
||||
"registration": {
|
||||
"bio": "Bio",
|
||||
|
@ -345,8 +346,8 @@
|
|||
"notification_visibility_moves": "Użytkownik migruje",
|
||||
"notification_visibility_emoji_reactions": "Reakcje",
|
||||
"no_rich_text_description": "Usuwaj formatowanie ze wszystkich postów",
|
||||
"no_blocks": "Bez blokad",
|
||||
"no_mutes": "Bez wyciszeń",
|
||||
"no_blocks": "Brak blokad",
|
||||
"no_mutes": "Brak wyciszeń",
|
||||
"hide_follows_description": "Nie pokazuj kogo obserwuję",
|
||||
"hide_followers_description": "Nie pokazuj kto mnie obserwuje",
|
||||
"hide_follows_count_description": "Nie pokazuj licznika obserwowanych",
|
||||
|
@ -488,7 +489,11 @@
|
|||
"selectedMenu": "Wybrany element menu",
|
||||
"disabled": "Wyłączone",
|
||||
"toggled": "Przełączone",
|
||||
"tabs": "Karty"
|
||||
"tabs": "Karty",
|
||||
"chat": {
|
||||
"outgoing": "Wiadomości wychodzące",
|
||||
"incoming": "Wiadomości przychodzące"
|
||||
}
|
||||
},
|
||||
"radii": {
|
||||
"_tab_label": "Zaokrąglenie"
|
||||
|
@ -563,9 +568,12 @@
|
|||
"reset_avatar": "Zresetuj awatar",
|
||||
"profile_fields": {
|
||||
"value": "Zawartość",
|
||||
"label": "Metadane profilu"
|
||||
"label": "Metadane profilu",
|
||||
"name": "Nazwa",
|
||||
"add_field": "Dodaj pole"
|
||||
},
|
||||
"bot": "To konto jest prowadzone przez bota"
|
||||
"bot": "To konto jest prowadzone przez bota",
|
||||
"notification_setting_hide_notification_contents": "Ukryj nadawcę i zawartość powiadomień push"
|
||||
},
|
||||
"time": {
|
||||
"day": "{0} dzień",
|
||||
|
@ -627,7 +635,11 @@
|
|||
"mute_conversation": "Wycisz konwersację",
|
||||
"unmute_conversation": "Odcisz konwersację",
|
||||
"status_unavailable": "Status niedostępny",
|
||||
"copy_link": "Kopiuj link do statusu"
|
||||
"copy_link": "Kopiuj link do statusu",
|
||||
"unbookmark": "Usuń z zakładek",
|
||||
"bookmark": "Dodaj do zakładek",
|
||||
"hide_content": "Ukryj zawartość",
|
||||
"show_content": "Pokaż zawartość"
|
||||
},
|
||||
"user_card": {
|
||||
"approve": "Przyjmij",
|
||||
|
@ -682,7 +694,8 @@
|
|||
"quarantine": "Zakaż federowania postów od tego użytkownika",
|
||||
"delete_user": "Usuń użytkownika",
|
||||
"delete_user_confirmation": "Czy jesteś absolutnie pewny(-a)? Ta operacja nie może być cofnięta."
|
||||
}
|
||||
},
|
||||
"message": "Napisz"
|
||||
},
|
||||
"user_profile": {
|
||||
"timeline_title": "Oś czasu użytkownika",
|
||||
|
@ -747,12 +760,21 @@
|
|||
"password_reset_required_but_mailer_is_disabled": "Musisz zresetować hasło, ale resetowanie hasła jest wyłączone. Proszę skontaktuj się z administratorem tej instancji."
|
||||
},
|
||||
"file_type": {
|
||||
"file": "Plik"
|
||||
"file": "Plik",
|
||||
"image": "Zdjęcie",
|
||||
"video": "Wideo",
|
||||
"audio": "Audio"
|
||||
},
|
||||
"chats": {
|
||||
"more": "Więcej",
|
||||
"delete": "Usuń",
|
||||
"you": "Ty:"
|
||||
"you": "Ty:",
|
||||
"delete_confirm": "Czy na pewno chcesz usunąć tą wiadomość?",
|
||||
"message_user": "Napisz do {nickname}",
|
||||
"error_sending_message": "Coś poszło nie tak podczas wysyłania wiadomości.",
|
||||
"error_loading_chat": "Coś poszło nie tak podczas ładowania czatu.",
|
||||
"empty_message_error": "Nie można wysłać pustej wiadomości",
|
||||
"new": "Nowy czat"
|
||||
},
|
||||
"display_date": {
|
||||
"today": "Dzisiaj"
|
||||
|
|
|
@ -16,7 +16,8 @@ const defaultState = {
|
|||
},
|
||||
mobileLayout: false,
|
||||
globalNotices: [],
|
||||
layoutHeight: 0
|
||||
layoutHeight: 0,
|
||||
lastTimeline: null
|
||||
}
|
||||
|
||||
const interfaceMod = {
|
||||
|
@ -69,6 +70,9 @@ const interfaceMod = {
|
|||
},
|
||||
setLayoutHeight (state, value) {
|
||||
state.layoutHeight = value
|
||||
},
|
||||
setLastTimeline (state, value) {
|
||||
state.lastTimeline = value
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
|
@ -117,6 +121,9 @@ const interfaceMod = {
|
|||
},
|
||||
setLayoutHeight ({ commit }, value) {
|
||||
commit('setLayoutHeight', value)
|
||||
},
|
||||
setLastTimeline ({ commit }, value) {
|
||||
commit('setLastTimeline', value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -505,6 +505,7 @@ const users = {
|
|||
store.commit('clearNotifications')
|
||||
store.commit('resetStatuses')
|
||||
store.dispatch('resetChats')
|
||||
store.dispatch('setLastTimeline', 'public-timeline')
|
||||
})
|
||||
},
|
||||
loginUser (store, accessToken) {
|
||||
|
|
|
@ -209,6 +209,7 @@ export const parseAttachment = (data) => {
|
|||
}
|
||||
|
||||
output.url = data.url
|
||||
output.large_thumb_url = data.preview_url
|
||||
output.description = data.description
|
||||
|
||||
return output
|
||||
|
|
|
@ -330,7 +330,7 @@ describe('Statuses module', () => {
|
|||
const deletion = makeMockStatus({ id: '4', type: 'deletion' })
|
||||
deletion.text = 'Dolus deleted notice {{tag:gs.smuglo.li,2016-11-18:noticeId=1038007:objectType=note}}.'
|
||||
deletion.uri = 'xxx'
|
||||
|
||||
const newNotificationSideEffects = () => {}
|
||||
mutations.addNewStatuses(state, { statuses: [status, otherStatus], user })
|
||||
mutations.addNewNotifications(
|
||||
state,
|
||||
|
@ -342,7 +342,8 @@ describe('Statuses module', () => {
|
|||
status: otherStatus,
|
||||
action: otherStatus,
|
||||
seen: false
|
||||
}]
|
||||
}],
|
||||
newNotificationSideEffects
|
||||
})
|
||||
|
||||
expect(state.notifications.data.length).to.eql(1)
|
||||
|
@ -356,7 +357,8 @@ describe('Statuses module', () => {
|
|||
status: mentionedStatus,
|
||||
action: mentionedStatus,
|
||||
seen: false
|
||||
}]
|
||||
}],
|
||||
newNotificationSideEffects
|
||||
})
|
||||
|
||||
mutations.addNewStatuses(state, { statuses: [mentionedStatus], user })
|
||||
|
|
|
@ -17,8 +17,7 @@ const message3 = {
|
|||
created_at: (new Date('2020-07-22T18:45:59.000Z'))
|
||||
}
|
||||
|
||||
// TODO: only
|
||||
describe.only('chatService', () => {
|
||||
describe('chatService', () => {
|
||||
describe('.add', () => {
|
||||
it("Doesn't add duplicates", () => {
|
||||
const chat = chatService.empty()
|
||||
|
|
Loading…
Reference in a new issue