Some initial work on replacing icons with FA5

This commit is contained in:
Henry Jameson 2020-10-19 19:38:49 +03:00
parent 350f25016f
commit 3814218277
34 changed files with 528 additions and 245 deletions

View file

@ -18,6 +18,10 @@
"dependencies": {
"@babel/runtime": "^7.7.6",
"@chenfengyuan/vue-qrcode": "^1.0.0",
"@fortawesome/fontawesome-svg-core": "^1.2.32",
"@fortawesome/free-regular-svg-icons": "^5.15.1",
"@fortawesome/free-solid-svg-icons": "^5.15.1",
"@fortawesome/vue-fontawesome": "^2.0.0",
"body-scroll-lock": "^2.6.4",
"chromatism": "^3.0.0",
"cropperjs": "^1.4.3",

View file

@ -318,7 +318,7 @@ option {
}
}
i[class*=icon-] {
i[class*=icon-], .svg-inline--fa {
color: $fallback--icon;
color: var(--icon, $fallback--icon);
}
@ -808,7 +808,12 @@ nav {
}
.button-icon {
font-size: 1.2em;
&i,
&.svg-inline--fa.fa-lg {
display: inline-block;
padding: 0 0.3em;
font-size: 1.1em;
}
}
@keyframes shakeError {

View file

@ -3,6 +3,15 @@ import EmojiPicker from '../emoji_picker/emoji_picker.vue'
import { take } from 'lodash'
import { findOffset } from '../../services/offset_finder/offset_finder.service.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faSmileBeam
} from '@fortawesome/free-regular-svg-icons'
library.add(
faSmileBeam
)
/**
* EmojiInput - augmented inputs for emoji and autocomplete support in inputs
* without having to give up the comfort of <input/> and <textarea/> elements

View file

@ -11,7 +11,7 @@
class="emoji-picker-icon"
@click.prevent="togglePicker"
>
<i class="icon-smile" />
<FAIcon :icon="['far', 'smile-beam']" />
</div>
<EmojiPicker
v-if="enableEmojiPicker"

View file

@ -1,4 +1,16 @@
import Checkbox from '../checkbox/checkbox.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faUnderline,
faStickyNote,
faSmileBeam
} from '@fortawesome/free-solid-svg-icons'
library.add(
faUnderline,
faStickyNote,
faSmileBeam
)
// At widest, approximately 20 emoji are visible in a row,
// loading 3 rows, could be overkill for narrow picker
@ -177,13 +189,13 @@ const EmojiPicker = {
{
id: 'custom',
text: this.$t('emoji.custom'),
icon: 'icon-smile',
icon: 'smile-beam',
emojis: customEmojis
},
{
id: 'standard',
text: this.$t('emoji.unicode'),
icon: 'icon-picture',
icon: 'underline',
emojis: filterByKeyword(standardEmojis, this.keyword)
}
]

View file

@ -82,7 +82,7 @@
&.active {
border-bottom: 4px solid;
i {
svg {
color: $fallback--lightText;
color: var(--lightText, $fallback--lightText);
}

View file

@ -13,7 +13,7 @@
:title="group.text"
@click.prevent="highlight(group.id)"
>
<i :class="group.icon" />
<FAIcon :icon="group.icon" fixed-width/>
</span>
</span>
<span
@ -26,7 +26,7 @@
:title="$t('emoji.stickers')"
@click.prevent="toggleStickers"
>
<i class="icon-star" />
<FAIcon icon="sticky-note" fixed-width/>
</span>
</span>
</div>

View file

@ -1,4 +1,8 @@
import Popover from '../popover/popover.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faEllipsisH } from '@fortawesome/free-solid-svg-icons'
library.add(faEllipsisH)
const ExtraButtons = {
props: [ 'status' ],

View file

@ -73,9 +73,11 @@
</button>
</div>
</div>
<i
<FAIcon
slot="trigger"
class="icon-ellipsis button-icon"
class="button-icon"
icon="ellipsis-h"
size="lg"
/>
</Popover>
</template>

View file

@ -1,4 +1,14 @@
import { mapGetters } from 'vuex'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faStar } from '@fortawesome/free-solid-svg-icons'
import {
faStar as faStarRegular
} from '@fortawesome/free-regular-svg-icons'
library.add(
faStar,
faStarRegular
)
const FavoriteButton = {
props: ['status', 'loggedIn'],
@ -23,9 +33,7 @@ const FavoriteButton = {
computed: {
classes () {
return {
'icon-star-empty': !this.status.favorited,
'icon-star': this.status.favorited,
'animate-spin': this.animated
'-favorited': this.status.favorited
}
},
...mapGetters(['mergedConfig'])

View file

@ -1,18 +1,23 @@
<template>
<div v-if="loggedIn">
<i
<FAIcon
:class="classes"
class="button-icon favorite-button fav-active"
class="FavoriteButton button-icon -interactive"
:title="$t('tool_tip.favorite')"
:icon="[status.favorited ? 'fas' : 'far', 'star']"
:spin="animated"
size="lg"
@click.prevent="favorite()"
/>
<span v-if="!mergedConfig.hidePostStats && status.fave_num > 0">{{ status.fave_num }}</span>
</div>
<div v-else>
<i
<FAIcon
:class="classes"
class="button-icon favorite-button"
class="FavoriteButton button-icon"
:title="$t('tool_tip.favorite')"
:icon="['far', 'star']"
size="lg"
/>
<span v-if="!mergedConfig.hidePostStats && status.fave_num > 0">{{ status.fave_num }}</span>
</div>
@ -23,7 +28,8 @@
<style lang="scss">
@import '../../_variables.scss';
.fav-active {
.FavoriteButton {
&.-interactive {
cursor: pointer;
animation-duration: 0.6s;
@ -33,8 +39,9 @@
}
}
.favorite-button.icon-star {
&.-favorited {
color: $fallback--cOrange;
color: var(--cOrange, $fallback--cOrange);
}
}
</style>

View file

@ -2,6 +2,14 @@
import statusPosterService from '../../services/status_poster/status_poster.service.js'
import fileSizeFormatService from '../../services/file_size_format/file_size_format.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faUpload, faCircleNotch } from '@fortawesome/free-solid-svg-icons'
library.add(
faUpload,
faCircleNotch
)
const mediaUpload = {
data () {
return {

View file

@ -7,13 +7,15 @@
class="label"
:title="$t('tool_tip.media_upload')"
>
<i
<FAIcon
v-if="uploading"
class="progress-icon icon-spin4 animate-spin"
class="progress-icon animate-spin"
icon="circle-notch"
/>
<i
<FAIcon
v-if="!uploading"
class="new-icon icon-upload"
class="new-icon"
icon="upload"
/>
<input
v-if="uploadReady"

View file

@ -1,6 +1,29 @@
import { timelineNames } from '../timeline_menu/timeline_menu.js'
import { mapState, mapGetters } from 'vuex'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faUsers,
faGlobeEurope,
faBookmark,
faEnvelope,
faHome,
faComments,
faBell,
faInfoCircle
} from '@fortawesome/free-solid-svg-icons'
library.add(
faUsers,
faGlobeEurope,
faBookmark,
faEnvelope,
faHome,
faComments,
faBell,
faInfoCircle
)
const NavPanel = {
created () {
if (this.currentUser && this.currentUser.locked) {

View file

@ -1,5 +1,5 @@
<template>
<div class="nav-panel">
<div class="NavPanel">
<div class="panel panel-default">
<ul>
<li v-if="currentUser || !privateMode">
@ -7,12 +7,14 @@
:to="{ name: timelinesRoute }"
:class="onTimelineRoute && 'router-link-active'"
>
<i class="button-icon icon-home-2" />{{ $t("nav.timelines") }}
<FAIcon fixed-width size="lg" class="button-icon" icon="home" />
{{ $t("nav.timelines") }}
</router-link>
</li>
<li v-if="currentUser">
<router-link :to="{ name: 'interactions', params: { username: currentUser.screen_name } }">
<i class="button-icon icon-bell-alt" />{{ $t("nav.interactions") }}
<FAIcon fixed-width size="lg" class="button-icon" icon="bell" />
{{ $t("nav.interactions") }}
</router-link>
</li>
<li v-if="currentUser && pleromaChatMessagesAvailable">
@ -23,12 +25,14 @@
>
{{ unreadChatCount }}
</div>
<i class="button-icon icon-chat" />{{ $t("nav.chats") }}
<FAIcon fixed-width size="lg" class="button-icon" icon="comments" />
{{ $t("nav.chats") }}
</router-link>
</li>
<li v-if="currentUser && currentUser.locked">
<router-link :to="{ name: 'friend-requests' }">
<i class="button-icon icon-user-plus" />{{ $t("nav.friend_requests") }}
<FAIcon fixed-width size="lg" class="button-icon" icon="user-plus" />
{{ $t("nav.friend_requests") }}
<span
v-if="followRequestCount > 0"
class="badge follow-request-count"
@ -39,7 +43,7 @@
</li>
<li>
<router-link :to="{ name: 'about' }">
<i class="button-icon icon-info-circled" />{{ $t("nav.about") }}
<FAIcon fixed-width size="lg" class="button-icon" icon="info-circle" />{{ $t("nav.about") }}
</router-link>
</li>
</ul>
@ -52,11 +56,13 @@
<style lang="scss">
@import '../../_variables.scss';
.nav-panel .panel {
.NavPanel {
.panel {
overflow: hidden;
box-shadow: var(--panelShadow);
}
.nav-panel ul {
ul {
list-style: none;
margin: 0;
padding: 0;
@ -68,7 +74,7 @@
background-color: var(--input, $fallback--faint);
}
.nav-panel li {
li {
border-bottom: 1px solid;
border-color: $fallback--border;
border-color: var(--border, $fallback--border);
@ -89,11 +95,11 @@
}
}
.nav-panel li:last-child {
li:last-child {
border: none;
}
.nav-panel a {
a {
display: block;
padding: 0.8em 0.85em;
@ -125,11 +131,13 @@
}
}
.nav-panel .button-icon {
margin-right: 0.5em;
.button-icon {
margin-left: -0.1em;
margin-right: 0.2em;
}
.nav-panel .button-icon:before {
.button-icon:before {
width: 1.1em;
}
}
</style>

View file

@ -1,5 +1,17 @@
import * as DateUtils from 'src/services/date_utils/date_utils.js'
import { uniq } from 'lodash'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faTimes,
faChevronDown,
faPlus
} from '@fortawesome/free-solid-svg-icons'
library.add(
faTimes,
faChevronDown,
faPlus
)
export default {
name: 'PollForm',

View file

@ -24,8 +24,8 @@
v-if="options.length > 2"
class="icon-container"
>
<i
class="icon-cancel"
<FAIcon
icon="times"
@click="deleteOption(index)"
/>
</div>
@ -35,7 +35,8 @@
class="add-option faint"
@click="addOption"
>
<i class="icon-plus" />
<FAIcon icon="plus" size="sm"/>
{{ $t("polls.add_option") }}
</a>
<div class="poll-type-expiry">
@ -55,7 +56,7 @@
<option value="single">{{ $t('polls.single_choice') }}</option>
<option value="multiple">{{ $t('polls.multiple_choices') }}</option>
</select>
<i class="icon-down-open" />
<FAIcon class="icon-down-open" icon="chevron-down"/>
</label>
</div>
<div
@ -83,7 +84,7 @@
{{ $t(`time.${unit}_short`, ['']) }}
</option>
</select>
<i class="icon-down-open" />
<FAIcon class="icon-down-open" icon="chevron-down"/>
</label>
</div>
</div>
@ -103,6 +104,7 @@
.add-option {
align-self: flex-start;
padding-top: 0.25em;
padding-left: 0.1em;
cursor: pointer;
}
@ -124,8 +126,8 @@
.icon-container {
// Hack: Move the icon over the input box
width: 2em;
margin-left: -2em;
width: 1.5em;
margin-left: -1.5em;
z-index: 1;
}

View file

@ -12,6 +12,23 @@ import suggestor from '../emoji_input/suggestor.js'
import { mapGetters, mapState } from 'vuex'
import Checkbox from '../checkbox/checkbox.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faChevronDown,
faSmileBeam,
faPollH,
faUpload,
faBan
} from '@fortawesome/free-solid-svg-icons'
library.add(
faChevronDown,
faSmileBeam,
faPollH,
faUpload,
faBan
)
const buildMentionsString = ({ user, attentions = [] }, currentUser) => {
let allAttentions = [...attentions]

View file

@ -12,10 +12,11 @@
v-show="showDropIcon !== 'hide'"
:style="{ animation: showDropIcon === 'show' ? 'fade-in 0.25s' : 'fade-out 0.5s' }"
class="drop-indicator"
:class="[uploadFileLimitReached ? 'icon-block' : 'icon-upload']"
@dragleave="fileDragStop"
@drop.stop="fileDrop"
/>
>
<FAIcon :icon="uploadFileLimitReached ? 'ban' : 'upload'"/>
</div>
<div class="form-group">
<i18n
v-if="!$store.state.users.currentUser.locked && newStatus.visibility == 'private' && !disableLockWarning"
@ -198,7 +199,7 @@
{{ $t(`post_status.content_type["${postFormat}"]`) }}
</option>
</select>
<i class="icon-down-open" />
<FAIcon class="icon-down-open" icon="chevron-down"/>
</label>
</div>
<div
@ -235,22 +236,22 @@
<div
class="emoji-icon"
>
<i
<div
:title="$t('emoji.add_emoji')"
class="icon-smile btn btn-default"
class="btn btn-default"
@click="showEmojiPicker"
/>
>
<FAIcon icon="smile-beam"/>
</div>
</div>
<div
v-if="pollsAvailable"
class="poll-icon"
:class="{ selected: pollFormVisible }"
>
<i
:title="$t('polls.add_poll')"
class="icon-chart-bar btn btn-default"
@click="togglePollForm"
/>
>
<FAIcon icon="poll-h" />
</div>
</div>
<button
@ -392,7 +393,7 @@
&:hover {
text-decoration: underline;
}
i {
svg, i {
margin-left: 0.2em;
font-size: 0.8em;
transform: rotate(90deg);
@ -434,18 +435,20 @@
.media-upload-icon, .poll-icon, .emoji-icon {
font-size: 26px;
line-height: 1.1;
flex: 1;
padding: 0 0.1em;
&.selected, &:hover {
// needs to be specific to override icon default color
i, label {
svg, i, label {
color: $fallback--lightText;
color: var(--lightText, $fallback--lightText);
}
}
&.disabled {
i {
svg, i {
cursor: not-allowed;
color: $fallback--icon;
color: var(--btnDisabledText, $fallback--icon);

View file

@ -1,4 +1,8 @@
import Popover from '../popover/popover.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faSmileBeam } from '@fortawesome/free-regular-svg-icons'
library.add(faSmileBeam)
const ReactButton = {
props: ['status'],

View file

@ -36,9 +36,11 @@
<div class="reaction-bottom-fader" />
</div>
</div>
<i
<FAIcon
slot="trigger"
class="icon-smile button-icon add-reaction-button"
class="button-icon add-reaction-button"
:icon="['far', 'smile-beam']"
size="lg"
:title="$t('tool_tip.add_reaction')"
/>
</Popover>

View file

@ -1,3 +1,7 @@
import { library } from '@fortawesome/fontawesome-svg-core'
import { faReply } from '@fortawesome/free-solid-svg-icons'
library.add(faReply)
const ReplyButton = {
name: 'ReplyButton',

View file

@ -1,15 +1,19 @@
<template>
<div>
<i
<FAIcon
v-if="loggedIn"
class="button-icon button-reply icon-reply"
class="ReplyButton button-icon -interactive"
icon="reply"
size="lg"
:title="$t('tool_tip.reply')"
:class="{'-active': replying}"
@click.prevent="$emit('toggle')"
/>
<i
<FAIcon
v-else
class="button-icon button-reply -disabled icon-reply"
icon="reply"
size="lg"
class="ReplyButton button-icon"
:title="$t('tool_tip.reply')"
/>
<span v-if="status.replies_count > 0">
@ -19,3 +23,19 @@
</template>
<script src="./reply_button.js"></script>
<style lang="scss">
@import '../../_variables.scss';
.ReplyButton {
&.-interactive {
cursor: pointer;
&:hover,
&.-active {
color: $fallback--cBlue;
color: var(--cBlue, $fallback--cBlue);
}
}
}
</style>

View file

@ -1,3 +1,7 @@
import { library } from '@fortawesome/fontawesome-svg-core'
import { faRetweet } from '@fortawesome/free-solid-svg-icons'
library.add(faRetweet)
const RetweetButton = {
props: ['status', 'loggedIn', 'visibility'],
@ -22,9 +26,7 @@ const RetweetButton = {
computed: {
classes () {
return {
'retweeted': this.status.repeated,
'retweeted-empty': !this.status.repeated,
'animate-spin': this.animated
'-repeated': this.status.repeated
}
},
mergedConfig () {

View file

@ -1,26 +1,33 @@
<template>
<div v-if="loggedIn">
<template v-if="visibility !== 'private' && visibility !== 'direct'">
<i
<FAIcon
:class="classes"
class="button-icon retweet-button icon-retweet rt-active"
class="RetweetButton button-icon -interactive"
icon="retweet"
size="lg"
:spin="animated"
:title="$t('tool_tip.repeat')"
@click.prevent="retweet()"
/>
<span v-if="!mergedConfig.hidePostStats && status.repeat_num > 0">{{ status.repeat_num }}</span>
</template>
<template v-else>
<i
<FAIcon
:class="classes"
class="button-icon icon-lock"
class="RetweetButton button-icon"
icon="lock"
size="lg"
:title="$t('timeline.no_retweet_hint')"
/>
</template>
</div>
<div v-else-if="!loggedIn">
<i
<FAIcon
:class="classes"
class="button-icon icon-retweet"
class="button-icon"
icon="retweet"
size="lg"
:title="$t('tool_tip.repeat')"
/>
<span v-if="!mergedConfig.hidePostStats && status.repeat_num > 0">{{ status.repeat_num }}</span>
@ -31,16 +38,21 @@
<style lang="scss">
@import '../../_variables.scss';
.rt-active {
.RetweetButton {
&.-interactive {
cursor: pointer;
animation-duration: 0.6s;
&:hover {
color: $fallback--cGreen;
color: var(--cGreen, $fallback--cGreen);
}
}
.icon-retweet.retweeted {
&.-repeated {
color: $fallback--cGreen;
color: var(--cGreen, $fallback--cGreen);
}
}
</style>

View file

@ -1,3 +1,18 @@
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faEnvelope,
faLock,
faLockOpen,
faGlobeEurope
} from '@fortawesome/free-solid-svg-icons'
library.add(
faEnvelope,
faGlobeEurope,
faLock,
faLockOpen
)
const ScopeSelector = {
props: [
'showAll',

View file

@ -1,36 +1,44 @@
<template>
<div
v-if="!showNothing"
class="scope-selector"
class="ScopeSelector"
>
<i
<span
v-if="showDirect"
class="icon-mail-alt"
class="scope"
:class="css.direct"
:title="$t('post_status.scope.direct')"
@click="changeVis('direct')"
/>
<i
>
<FAIcon icon="envelope" class="button-icon" size="lg" />
</span>
<span
class="scope"
v-if="showPrivate"
class="icon-lock"
:class="css.private"
:title="$t('post_status.scope.private')"
@click="changeVis('private')"
/>
<i
>
<FAIcon icon="lock" class="button-icon" size="lg" />
</span>
<span
v-if="showUnlisted"
class="icon-lock-open-alt"
class="scope"
:class="css.unlisted"
:title="$t('post_status.scope.unlisted')"
@click="changeVis('unlisted')"
/>
<i
>
<FAIcon icon="lock-open" class="button-icon" size="lg" />
</span>
<span
v-if="showPublic"
class="icon-globe"
class="scope"
:class="css.public"
:title="$t('post_status.scope.public')"
@click="changeVis('public')"
/>
>
<FAIcon icon="globe-europe" class="button-icon" size="lg" />
</span>
</div>
</template>
@ -39,12 +47,16 @@
<style lang="scss">
@import '../../_variables.scss';
.scope-selector {
i {
font-size: 1.2em;
cursor: pointer;
.ScopeSelector {
&.selected {
.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);
}

View file

@ -17,6 +17,47 @@ import { highlightClass, highlightStyle } from '../../services/user_highlighter/
import { muteWordHits } from '../../services/status_parser/status_parser.js'
import { unescape, uniqBy } from 'lodash'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faEnvelope,
faLock,
faLockOpen,
faGlobeEurope,
faTimes,
faRetweet,
faReply,
faExternalLinkSquareAlt,
faPlusSquare,
faSmileBeam,
faEllipsisH,
faStar,
faEyeSlash,
faEye,
faThumbtack
} from '@fortawesome/free-solid-svg-icons'
import {
faStar as faStarRegular
} from '@fortawesome/free-regular-svg-icons'
library.add(
faEnvelope,
faGlobeEurope,
faLock,
faLockOpen,
faTimes,
faRetweet,
faReply,
faExternalLinkSquareAlt,
faPlusSquare,
faStar,
faStarRegular,
faSmileBeam,
faEllipsisH,
faEyeSlash,
faEye,
faThumbtack
)
const Status = {
name: 'Status',
components: {
@ -227,13 +268,13 @@ const Status = {
visibilityIcon (visibility) {
switch (visibility) {
case 'private':
return 'icon-lock'
return 'lock'
case 'unlisted':
return 'icon-lock-open-alt'
return 'lock-open'
case 'direct':
return 'icon-mail-alt'
return 'envelope'
default:
return 'icon-globe'
return 'globe-europe'
}
},
showError (error) {

View file

@ -200,7 +200,6 @@ $status-margin: 0.75em;
}
.reply-to {
display: flex;
position: relative;
}
@ -208,7 +207,6 @@ $status-margin: 0.75em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-left: 0.2em;
}
.replies-separator {
@ -232,16 +230,10 @@ $status-margin: 0.75em;
.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;
.repeat-icon {
color: $fallback--cGreen;
color: var(--cGreen, $fallback--cGreen);
}
}
@ -291,18 +283,6 @@ $status-margin: 0.75em;
}
}
.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;

View file

@ -10,17 +10,20 @@
class="alert error"
>
{{ error }}
<i
class="button-icon icon-cancel"
<span
class="button-icon"
@click="clearError"
/>
>
<FAIcon icon="times" />
</span>
</div>
<template v-if="muted && !isPreview">
<div class="status-container muted">
<small class="status-username">
<i
<FAIcon
v-if="muted && retweet"
class="button-icon icon-retweet"
class="button-icon repeat-icon"
icon="retweet"
/>
<router-link :to="userProfileLink">
{{ status.user.screen_name }}
@ -46,9 +49,11 @@
</small>
<a
href="#"
class="unmute"
class="unmute button-icon"
@click.prevent="toggleMute"
><i class="button-icon icon-eye-off" /></a>
>
<FAIcon icon="eye-slash" class="button-icon" size="lg" />
</a>
</div>
</template>
<template v-else>
@ -56,7 +61,7 @@
v-if="showPinned"
class="pin"
>
<i class="fa icon-pin faint" />
<FAIcon icon="thumbtack" class="faint" />
<span class="faint">{{ $t('status.pinned') }}</span>
</div>
<div
@ -86,8 +91,9 @@
:to="retweeterProfileLink"
>{{ retweeter }}</router-link>
</span>
<i
class="fa icon-retweet retweeted"
<FAIcon
icon="retweet"
class="repeat-icon"
:title="$t('tool_tip.repeat')"
/>
{{ $t('timeline.repeated') }}
@ -167,15 +173,13 @@
:auto-update="60"
/>
</router-link>
<div
<span
v-if="status.visibility"
class="button-icon visibility-icon"
>
<i
:class="visibilityIcon(status.visibility)"
class="visibility-icon"
:title="status.visibility | capitalize"
/>
</div>
>
<FAIcon class="button-icon" :icon="visibilityIcon(status.visibility)" size="lg" />
</span>
<a
v-if="!status.is_local && !isPreview"
:href="status.external_url"
@ -183,22 +187,23 @@
class="source_url"
title="Source"
>
<i class="button-icon icon-link-ext-alt" />
<FAIcon class="button-icon" icon="external-link-square-alt" size="lg" />
</a>
<template v-if="expandable && !isPreview">
<a
v-if="expandable && !isPreview"
href="#"
title="Expand"
@click.prevent="toggleExpanded"
>
<i class="button-icon icon-plus-squared" />
<FAIcon class="button-icon" icon="plus-square" size="lg" />
</a>
</template>
<a
v-if="unmuted"
href="#"
@click.prevent="toggleMute"
><i class="button-icon icon-eye-off" /></a>
>
<FAIcon icon="eye-slash" class="button-icon" size="lg" />
</a>
</span>
</div>
@ -220,7 +225,12 @@
:aria-label="$t('tool_tip.reply')"
@click.prevent="gotoOriginal(status.in_reply_to_status_id)"
>
<i class="button-icon reply-button icon-reply" />
<FAIcon
class="button-icon"
icon="reply"
size="lg"
flip="horizontal"
/>
<span
class="faint-link reply-to-text"
>

View file

@ -1,5 +1,23 @@
import Popover from '../popover/popover.vue'
import { mapState } from 'vuex'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faUsers,
faGlobeEurope,
faBookmark,
faEnvelope,
faHome,
faChevronDown
} from '@fortawesome/free-solid-svg-icons'
library.add(
faUsers,
faGlobeEurope,
faBookmark,
faEnvelope,
faHome,
faChevronDown
)
// Route -> i18n key mapping, exported andnot in the computed
// because nav panel benefits from the same information.

View file

@ -1,7 +1,7 @@
<template>
<Popover
trigger="click"
class="timeline-menu"
class="TimelineMenu"
:class="{ 'open': isOpen }"
:margin="{ left: -15, right: -200 }"
:bound-to="{ x: 'container' }"
@ -16,27 +16,27 @@
<ul>
<li v-if="currentUser">
<router-link :to="{ name: 'friends' }">
<i class="button-icon icon-home-2" />{{ $t("nav.timeline") }}
<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'}">
<i class="button-icon icon-bookmark" />{{ $t("nav.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 } }">
<i class="button-icon icon-mail-alt" />{{ $t("nav.dms") }}
<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' }">
<i class="button-icon icon-users" />{{ $t("nav.public_tl") }}
<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' }">
<i class="button-icon icon-globe" />{{ $t("nav.twkn") }}
<FAIcon fixed-width size="lg" class="button-icon " icon="globe-europe" />{{ $t("nav.twkn") }}
</router-link>
</li>
</ul>
@ -46,7 +46,7 @@
class="title timeline-menu-title"
>
<span>{{ timelineName() }}</span>
<i class="icon-down-open" />
<FAIcon size="sm" icon="chevron-down" />
</div>
</Popover>
</template>
@ -56,17 +56,19 @@
<style lang="scss">
@import '../../_variables.scss';
.timeline-menu {
.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;
@ -77,10 +79,12 @@
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);
}
@ -88,7 +92,6 @@
.timeline-menu-title {
margin: 0;
cursor: pointer;
display: flex;
user-select: none;
width: 100%;
@ -98,15 +101,13 @@
white-space: nowrap;
}
i {
svg {
margin-left: 0.6em;
flex-shrink: 0;
font-size: 1rem;
transition: transform 100ms;
}
}
&.open .timeline-menu-title i {
&.open .timeline-menu-title svg {
color: $fallback--text;
color: var(--panelText, $fallback--text);
transform: rotate(180deg);
@ -171,8 +172,9 @@
}
}
i {
margin-right: 0.5em;
svg {
margin-right: 0.4em;
margin-left: -0.2em;
}
}
}

View file

@ -33,6 +33,8 @@ import VueClickOutside from 'v-click-outside'
import PortalVue from 'portal-vue'
import VBodyScrollLock from './directives/body_scroll_lock'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import afterStoreSetup from './boot/after_store.js'
const currentLocale = (window.navigator.language || 'en').split('-')[0]
@ -45,6 +47,8 @@ Vue.use(VueClickOutside)
Vue.use(PortalVue)
Vue.use(VBodyScrollLock)
Vue.component('FAIcon', FontAwesomeIcon)
const i18n = new VueI18n({
// By default, use the browser locale, we will update it if neccessary
locale: 'en',

View file

@ -884,6 +884,37 @@
dependencies:
qrcode "^1.3.0"
"@fortawesome/fontawesome-common-types@^0.2.32":
version "0.2.32"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.32.tgz#3436795d5684f22742989bfa08f46f50f516f259"
integrity sha512-ux2EDjKMpcdHBVLi/eWZynnPxs0BtFVXJkgHIxXRl+9ZFaHPvYamAfCzeeQFqHRjuJtX90wVnMRaMQAAlctz3w==
"@fortawesome/fontawesome-svg-core@^1.2.32":
version "1.2.32"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.32.tgz#da092bfc7266aa274be8604de610d7115f9ba6cf"
integrity sha512-XjqyeLCsR/c/usUpdWcOdVtWFVjPbDFBTQkn2fQRrWhhUoxriQohO2RWDxLyUM8XpD+Zzg5xwJ8gqTYGDLeGaQ==
dependencies:
"@fortawesome/fontawesome-common-types" "^0.2.32"
"@fortawesome/free-regular-svg-icons@^5.15.1":
version "5.15.1"
resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.15.1.tgz#a8897d0ce325352dbba0e943101323e0175ee2b2"
integrity sha512-eD9NWFy89e7SVVtrLedJUxIpCBGhd4x7s7dhesokjyo1Tw62daqN5UcuAGu1NrepLLq1IeAYUVfWwnOjZ/j3HA==
dependencies:
"@fortawesome/fontawesome-common-types" "^0.2.32"
"@fortawesome/free-solid-svg-icons@^5.15.1":
version "5.15.1"
resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.1.tgz#e1432676ddd43108b41197fee9f86d910ad458ef"
integrity sha512-EFMuKtzRMNbvjab/SvJBaOOpaqJfdSap/Nl6hst7CgrJxwfORR1drdTV6q1Ib/JVzq4xObdTDcT6sqTaXMqfdg==
dependencies:
"@fortawesome/fontawesome-common-types" "^0.2.32"
"@fortawesome/vue-fontawesome@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@fortawesome/vue-fontawesome/-/vue-fontawesome-2.0.0.tgz#63da3e459147cebb0a8d58eed81d6071db9f5973"
integrity sha512-N3VKw7KzRfOm8hShUVldpinlm13HpvLBQgT63QS+aCrIRLwjoEUXY5Rcmttbfb6HkzZaeqjLqd/aZCQ53UjQpg==
"@nodelib/fs.scandir@2.1.3":
version "2.1.3"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b"