Page MenuHomePhorge

No OneTemporary

Authored By
Unknown
Size
24 KB
Referenced Files
None
Subscribers
None
diff --git a/src/components/nav_panel/nav_panel.js b/src/components/nav_panel/nav_panel.js
index 87e54133ab..81d49cc260 100644
--- a/src/components/nav_panel/nav_panel.js
+++ b/src/components/nav_panel/nav_panel.js
@@ -1,54 +1,54 @@
import { timelineNames } from '../timeline_menu/timeline_menu.js'
import { mapState, mapGetters } from 'vuex'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faUsers,
- faGlobeEurope,
+ faGlobe,
faBookmark,
faEnvelope,
faHome,
faComments,
faBell,
faInfoCircle
} from '@fortawesome/free-solid-svg-icons'
library.add(
faUsers,
- faGlobeEurope,
+ faGlobe,
faBookmark,
faEnvelope,
faHome,
faComments,
faBell,
faInfoCircle
)
const NavPanel = {
created () {
if (this.currentUser && this.currentUser.locked) {
this.$store.dispatch('startFetchingFollowRequests')
}
},
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,
followRequestCount: state => state.api.followRequests.length,
privateMode: state => state.instance.private,
federating: state => state.instance.federating,
pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable
}),
...mapGetters(['unreadChatCount'])
}
}
export default NavPanel
diff --git a/src/components/scope_selector/scope_selector.js b/src/components/scope_selector/scope_selector.js
index ddb20ff272..2c9d06e093 100644
--- a/src/components/scope_selector/scope_selector.js
+++ b/src/components/scope_selector/scope_selector.js
@@ -1,69 +1,69 @@
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faEnvelope,
faLock,
faUnlock,
- faGlobeEurope
+ faGlobe
} from '@fortawesome/free-solid-svg-icons'
library.add(
faEnvelope,
- faGlobeEurope,
+ faGlobe,
faLock,
faUnlock
)
const ScopeSelector = {
props: [
'showAll',
'userDefault',
'originalScope',
'initialScope',
'onScopeChange'
],
data () {
return {
currentScope: this.initialScope
}
},
computed: {
showNothing () {
return !this.showPublic && !this.showUnlisted && !this.showPrivate && !this.showDirect
},
showPublic () {
return this.originalScope !== 'direct' && this.shouldShow('public')
},
showUnlisted () {
return this.originalScope !== 'direct' && this.shouldShow('unlisted')
},
showPrivate () {
return this.originalScope !== 'direct' && this.shouldShow('private')
},
showDirect () {
return this.shouldShow('direct')
},
css () {
return {
public: { selected: this.currentScope === 'public' },
unlisted: { selected: this.currentScope === 'unlisted' },
private: { selected: this.currentScope === 'private' },
direct: { selected: this.currentScope === 'direct' }
}
}
},
methods: {
shouldShow (scope) {
return this.showAll ||
this.currentScope === scope ||
this.originalScope === scope ||
this.userDefault === scope ||
scope === 'direct'
},
changeVis (scope) {
this.currentScope = scope
this.onScopeChange && this.onScopeChange(scope)
}
}
}
export default ScopeSelector
diff --git a/src/components/scope_selector/scope_selector.vue b/src/components/scope_selector/scope_selector.vue
index ddd894223a..c098783d65 100644
--- a/src/components/scope_selector/scope_selector.vue
+++ b/src/components/scope_selector/scope_selector.vue
@@ -1,65 +1,65 @@
<template>
<div
v-if="!showNothing"
class="ScopeSelector"
>
<span
v-if="showDirect"
class="scope"
:class="css.direct"
:title="$t('post_status.scope.direct')"
@click="changeVis('direct')"
>
<FAIcon icon="envelope" class="button-icon" size="lg" />
</span>
<span
class="scope"
v-if="showPrivate"
:class="css.private"
:title="$t('post_status.scope.private')"
@click="changeVis('private')"
>
<FAIcon icon="lock" class="button-icon" size="lg" />
</span>
<span
v-if="showUnlisted"
class="scope"
:class="css.unlisted"
:title="$t('post_status.scope.unlisted')"
@click="changeVis('unlisted')"
>
<FAIcon icon="unlock" class="button-icon" size="lg" />
</span>
<span
v-if="showPublic"
class="scope"
:class="css.public"
:title="$t('post_status.scope.public')"
@click="changeVis('public')"
>
- <FAIcon icon="globe-europe" class="button-icon" size="lg" />
+ <FAIcon icon="globe" class="button-icon" size="lg" />
</span>
</div>
</template>
<script src="./scope_selector.js"></script>
<style lang="scss">
@import '../../_variables.scss';
.ScopeSelector {
.scope {
display: inline-block;
cursor: pointer;
min-width: 1.3em;
min-height: 1.3em;
text-align: center;
&.selected svg {
color: $fallback--lightText;
color: var(--lightText, $fallback--lightText);
}
}
}
</style>
diff --git a/src/components/status/status.js b/src/components/status/status.js
index 5b93054f3d..46fa3b7664 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -1,348 +1,348 @@
import ReplyButton from '../reply_button/reply_button.vue'
import FavoriteButton from '../favorite_button/favorite_button.vue'
import ReactButton from '../react_button/react_button.vue'
import RetweetButton from '../retweet_button/retweet_button.vue'
import ExtraButtons from '../extra_buttons/extra_buttons.vue'
import PostStatusForm from '../post_status_form/post_status_form.vue'
import UserCard from '../user_card/user_card.vue'
import UserAvatar from '../user_avatar/user_avatar.vue'
import AvatarList from '../avatar_list/avatar_list.vue'
import Timeago from '../timeago/timeago.vue'
import StatusContent from '../status_content/status_content.vue'
import StatusPopover from '../status_popover/status_popover.vue'
import UserListPopover from '../user_list_popover/user_list_popover.vue'
import EmojiReactions from '../emoji_reactions/emoji_reactions.vue'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
import { muteWordHits } from '../../services/status_parser/status_parser.js'
import { unescape, uniqBy } from 'lodash'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faEnvelope,
faLock,
faUnlock,
- faGlobeEurope,
+ faGlobe,
faTimes,
faRetweet,
faReply,
faExternalLinkSquareAlt,
faPlusSquare,
faSmileBeam,
faEllipsisH,
faStar,
faEyeSlash,
faEye,
faThumbtack
} from '@fortawesome/free-solid-svg-icons'
library.add(
faEnvelope,
- faGlobeEurope,
+ faGlobe,
faLock,
faUnlock,
faTimes,
faRetweet,
faReply,
faExternalLinkSquareAlt,
faPlusSquare,
faStar,
faSmileBeam,
faEllipsisH,
faEyeSlash,
faEye,
faThumbtack
)
const Status = {
name: 'Status',
components: {
ReplyButton,
FavoriteButton,
ReactButton,
RetweetButton,
ExtraButtons,
PostStatusForm,
UserCard,
UserAvatar,
AvatarList,
Timeago,
StatusPopover,
UserListPopover,
EmojiReactions,
StatusContent
},
props: [
'statusoid',
'expandable',
'inConversation',
'focused',
'highlight',
'compact',
'replies',
'isPreview',
'noHeading',
'inlineExpanded',
'showPinned',
'inProfile',
'profileUserId'
],
data () {
return {
replying: false,
unmuted: false,
userExpanded: false,
mediaPlaying: [],
suspendable: true,
error: null
}
},
computed: {
muteWords () {
return this.mergedConfig.muteWords
},
showReasonMutedThread () {
return (
this.status.thread_muted ||
(this.status.reblog && this.status.reblog.thread_muted)
) && !this.inConversation
},
repeaterClass () {
const user = this.statusoid.user
return highlightClass(user)
},
userClass () {
const user = this.retweet ? (this.statusoid.retweeted_status.user) : this.statusoid.user
return highlightClass(user)
},
deleted () {
return this.statusoid.deleted
},
repeaterStyle () {
const user = this.statusoid.user
const highlight = this.mergedConfig.highlight
return highlightStyle(highlight[user.screen_name])
},
userStyle () {
if (this.noHeading) return
const user = this.retweet ? (this.statusoid.retweeted_status.user) : this.statusoid.user
const highlight = this.mergedConfig.highlight
return highlightStyle(highlight[user.screen_name])
},
userProfileLink () {
return this.generateUserProfileLink(this.status.user.id, this.status.user.screen_name)
},
replyProfileLink () {
if (this.isReply) {
return this.generateUserProfileLink(this.status.in_reply_to_user_id, this.replyToName)
}
},
retweet () { return !!this.statusoid.retweeted_status },
retweeter () { return this.statusoid.user.name || this.statusoid.user.screen_name },
retweeterHtml () { return this.statusoid.user.name_html },
retweeterProfileLink () { return this.generateUserProfileLink(this.statusoid.user.id, this.statusoid.user.screen_name) },
status () {
if (this.retweet) {
return this.statusoid.retweeted_status
} else {
return this.statusoid
}
},
statusFromGlobalRepository () {
// NOTE: Consider to replace status with statusFromGlobalRepository
return this.$store.state.statuses.allStatusesObject[this.status.id]
},
loggedIn () {
return !!this.currentUser
},
muteWordHits () {
return muteWordHits(this.status, this.muteWords)
},
muted () {
const { status } = this
const { reblog } = status
const relationship = this.$store.getters.relationship(status.user.id)
const relationshipReblog = reblog && this.$store.getters.relationship(reblog.user.id)
const reasonsToMute = (
// Post is muted according to BE
status.muted ||
// Reprööt of a muted post according to BE
(reblog && reblog.muted) ||
// Muted user
relationship.muting ||
// Muted user of a reprööt
(relationshipReblog && relationshipReblog.muting) ||
// Thread is muted
status.thread_muted ||
// Wordfiltered
this.muteWordHits.length > 0
)
const excusesNotToMute = (
(
this.inProfile && (
// Don't mute user's posts on user timeline (except reblogs)
(!reblog && status.user.id === this.profileUserId) ||
// Same as above but also allow self-reblogs
(reblog && reblog.user.id === this.profileUserId)
)
) ||
// Don't mute statuses in muted conversation when said conversation is opened
(this.inConversation && status.thread_muted)
// No excuses if post has muted words
) && !this.muteWordHits.length > 0
return !this.unmuted && !excusesNotToMute && reasonsToMute
},
hideFilteredStatuses () {
return this.mergedConfig.hideFilteredStatuses
},
hideStatus () {
return (this.muted && this.hideFilteredStatuses) || this.virtualHidden
},
isFocused () {
// retweet or root of an expanded conversation
if (this.focused) {
return true
} else if (!this.inConversation) {
return false
}
// use conversation highlight only when in conversation
return this.status.id === this.highlight
},
isReply () {
return !!(this.status.in_reply_to_status_id && this.status.in_reply_to_user_id)
},
replyToName () {
if (this.status.in_reply_to_screen_name) {
return this.status.in_reply_to_screen_name
} else {
const user = this.$store.getters.findUser(this.status.in_reply_to_user_id)
return user && user.screen_name
}
},
replySubject () {
if (!this.status.summary) return ''
const decodedSummary = unescape(this.status.summary)
const behavior = this.mergedConfig.subjectLineBehavior
const startsWithRe = decodedSummary.match(/^re[: ]/i)
if ((behavior !== 'noop' && startsWithRe) || behavior === 'masto') {
return decodedSummary
} else if (behavior === 'email') {
return 're: '.concat(decodedSummary)
} else if (behavior === 'noop') {
return ''
}
},
combinedFavsAndRepeatsUsers () {
// Use the status from the global status repository since favs and repeats are saved in it
const combinedUsers = [].concat(
this.statusFromGlobalRepository.favoritedBy,
this.statusFromGlobalRepository.rebloggedBy
)
return uniqBy(combinedUsers, 'id')
},
tags () {
return this.status.tags.filter(tagObj => tagObj.hasOwnProperty('name')).map(tagObj => tagObj.name).join(' ')
},
hidePostStats () {
return this.mergedConfig.hidePostStats
},
currentUser () {
return this.$store.state.users.currentUser
},
betterShadow () {
return this.$store.state.interface.browserSupport.cssFilter
},
mergedConfig () {
return this.$store.getters.mergedConfig
},
isSuspendable () {
return !this.replying && this.mediaPlaying.length === 0
}
},
methods: {
visibilityIcon (visibility) {
switch (visibility) {
case 'private':
return 'lock'
case 'unlisted':
return 'unlock'
case 'direct':
return 'envelope'
default:
- return 'globe-europe'
+ return 'globe'
}
},
showError (error) {
this.error = error
},
clearError () {
this.error = undefined
},
toggleReplying () {
this.replying = !this.replying
},
gotoOriginal (id) {
if (this.inConversation) {
this.$emit('goto', id)
}
},
toggleExpanded () {
this.$emit('toggleExpanded')
},
toggleMute () {
this.unmuted = !this.unmuted
},
toggleUserExpanded () {
this.userExpanded = !this.userExpanded
},
generateUserProfileLink (id, name) {
return generateProfileLink(id, name, this.$store.state.instance.restrictedNicknames)
},
addMediaPlaying (id) {
this.mediaPlaying.push(id)
},
removeMediaPlaying (id) {
this.mediaPlaying = this.mediaPlaying.filter(mediaId => mediaId !== id)
}
},
watch: {
'highlight': function (id) {
if (this.status.id === id) {
let rect = this.$el.getBoundingClientRect()
if (rect.top < 100) {
// Post is above screen, match its top to screen top
window.scrollBy(0, rect.top - 100)
} else if (rect.height >= (window.innerHeight - 50)) {
// Post we want to see is taller than screen so match its top to screen top
window.scrollBy(0, rect.top - 100)
} else if (rect.bottom > window.innerHeight - 50) {
// Post is below screen, match its bottom to screen bottom
window.scrollBy(0, rect.bottom - window.innerHeight + 50)
}
}
},
'status.repeat_num': function (num) {
// refetch repeats when repeat_num is changed in any way
if (this.isFocused && this.statusFromGlobalRepository.rebloggedBy && this.statusFromGlobalRepository.rebloggedBy.length !== num) {
this.$store.dispatch('fetchRepeats', this.status.id)
}
},
'status.fave_num': function (num) {
// refetch favs when fave_num is changed in any way
if (this.isFocused && this.statusFromGlobalRepository.favoritedBy && this.statusFromGlobalRepository.favoritedBy.length !== num) {
this.$store.dispatch('fetchFavs', this.status.id)
}
},
'isSuspendable': function (val) {
this.suspendable = val
}
},
filters: {
capitalize: function (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
}
}
export default Status
diff --git a/src/components/timeline_menu/timeline_menu.js b/src/components/timeline_menu/timeline_menu.js
index 991c600d11..4ccd52b4c7 100644
--- a/src/components/timeline_menu/timeline_menu.js
+++ b/src/components/timeline_menu/timeline_menu.js
@@ -1,81 +1,81 @@
import Popover from '../popover/popover.vue'
import { mapState } from 'vuex'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faUsers,
- faGlobeEurope,
+ faGlobe,
faBookmark,
faEnvelope,
faHome,
faChevronDown
} from '@fortawesome/free-solid-svg-icons'
library.add(
faUsers,
- faGlobeEurope,
+ faGlobe,
faBookmark,
faEnvelope,
faHome,
faChevronDown
)
// 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
diff --git a/src/components/timeline_menu/timeline_menu.vue b/src/components/timeline_menu/timeline_menu.vue
index 590752d312..1e546faecd 100644
--- a/src/components/timeline_menu/timeline_menu.vue
+++ b/src/components/timeline_menu/timeline_menu.vue
@@ -1,182 +1,182 @@
<template>
<Popover
trigger="click"
class="TimelineMenu"
: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' }">
<FAIcon fixed-width size="lg" class="button-icon " icon="home" />{{ $t("nav.timeline") }}
</router-link>
</li>
<li v-if="currentUser">
<router-link :to="{ name: 'bookmarks'}">
<FAIcon fixed-width size="lg" 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 } }">
<FAIcon fixed-width size="lg" class="button-icon " icon="envelope" />{{ $t("nav.dms") }}
</router-link>
</li>
<li v-if="currentUser || !privateMode">
<router-link :to="{ name: 'public-timeline' }">
<FAIcon fixed-width size="lg" 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' }">
- <FAIcon fixed-width size="lg" class="button-icon " icon="globe-europe" />{{ $t("nav.twkn") }}
+ <FAIcon fixed-width size="lg" class="button-icon " icon="globe" />{{ $t("nav.twkn") }}
</router-link>
</li>
</ul>
</div>
<div
slot="trigger"
class="title timeline-menu-title"
>
<span>{{ timelineName() }}</span>
<FAIcon size="sm" icon="chevron-down" />
</div>
</Popover>
</template>
<script src="./timeline_menu.js" ></script>
<style lang="scss">
@import '../../_variables.scss';
.TimelineMenu {
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;
user-select: none;
width: 100%;
span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
svg {
margin-left: 0.6em;
transition: transform 100ms;
}
}
&.open .timeline-menu-title svg {
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;
}
}
a {
display: block;
padding: 0.6em 0.65em;
&: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;
}
}
svg {
margin-right: 0.4em;
margin-left: -0.2em;
}
}
}
</style>

File Metadata

Mime Type
text/x-diff
Expires
Sun, Nov 1, 6:58 AM (11 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1802724
Default Alt Text
(24 KB)

Event Timeline