Page MenuHomePhorge

No OneTemporary

Authored By
Unknown
Size
39 KB
Referenced Files
None
Subscribers
None
diff --git a/src/components/emoji_input/emoji_input.vue b/src/components/emoji_input/emoji_input.vue
index 63bf856e04..c9bbc18f02 100644
--- a/src/components/emoji_input/emoji_input.vue
+++ b/src/components/emoji_input/emoji_input.vue
@@ -1,202 +1,209 @@
<template>
<div
ref="root"
class="emoji-input"
:class="{ 'with-picker': !hideEmojiButton }"
>
<slot />
<!-- TODO: make the 'x' disappear if at the end maybe? -->
- <div class="hidden-overlay" :style="overlayStyle" ref="hiddenOverlay">
+ <div
+ ref="hiddenOverlay"
+ class="hidden-overlay"
+ :style="overlayStyle"
+ >
<span>{{ preText }}</span>
- <span class="caret" ref="hiddenOverlayCaret">x</span>
+ <span
+ ref="hiddenOverlayCaret"
+ class="caret"
+ >x</span>
<span>{{ postText }}</span>
</div>
<template v-if="enableEmojiPicker">
<button
v-if="!hideEmojiButton"
class="button-unstyled emoji-picker-icon"
type="button"
@click.prevent="togglePicker"
>
<FAIcon :icon="['far', 'smile-beam']" />
</button>
<EmojiPicker
v-if="enableEmojiPicker"
ref="picker"
:enable-sticker-picker="enableStickerPicker"
class="emoji-picker-panel"
@emoji="insert"
@sticker-uploaded="onStickerUploaded"
@sticker-upload-failed="onStickerUploadFailed"
@show="onPickerShown"
@close="onPickerClosed"
/>
</template>
<Popover
+ ref="suggestorPopover"
class="autocomplete-panel"
placement="bottom"
- ref="suggestorPopover"
>
<template #content>
<div
ref="panel-body"
class="autocomplete-panel-body"
>
<div
v-for="(suggestion, index) in suggestions"
:key="index"
class="autocomplete-item"
:class="{ highlighted: index === highlighted }"
@click.stop.prevent="onClick($event, suggestion)"
>
<span class="image">
<img
v-if="suggestion.img"
:src="suggestion.img"
>
<span v-else>{{ suggestion.replacement }}</span>
</span>
<div class="label">
<span
v-if="suggestion.user"
class="displayText"
>
{{ suggestion.displayText }}<UnicodeDomainIndicator
:user="suggestion.user"
:at="false"
/>
</span>
<span
v-if="!suggestion.user"
class="displayText"
>
{{ maybeLocalizedEmojiName(suggestion) }}
</span>
<span class="detailText">{{ suggestion.detailText }}</span>
</div>
</div>
</div>
</template>
</Popover>
</div>
</template>
<script src="./emoji_input.js"></script>
<style lang="scss">
@import '../../_variables.scss';
.emoji-input {
display: flex;
flex-direction: column;
position: relative;
&.with-picker input {
padding-right: 30px;
}
.emoji-picker-icon {
position: absolute;
top: 0;
right: 0;
margin: .2em .25em;
font-size: 1.3em;
cursor: pointer;
line-height: 24px;
&:hover i {
color: $fallback--text;
color: var(--text, $fallback--text);
}
}
.emoji-picker-panel {
position: absolute;
z-index: 20;
margin-top: 2px;
&.hide {
display: none
}
}
input, textarea {
flex: 1 0 auto;
}
.hidden-overlay {
opacity: 0;
pointer-events: none;
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
overflow: hidden;
/* DEBUG STUFF */
color: red;
/* set opacity to non-zero to see the overlay */
.caret {
width: 0;
margin-right: calc(-1ch - 1px);
border: 1px solid red;
}
}
}
.autocomplete {
&-panel {
position: absolute;
}
&-item {
display: flex;
cursor: pointer;
padding: 0.2em 0.4em;
border-bottom: 1px solid rgba(0, 0, 0, 0.4);
height: 32px;
.image {
width: 32px;
height: 32px;
line-height: 32px;
text-align: center;
font-size: 32px;
margin-right: 4px;
img {
width: 32px;
height: 32px;
object-fit: contain;
}
}
.label {
display: flex;
flex-direction: column;
justify-content: center;
margin: 0 0.1em 0 0.2em;
.displayText {
line-height: 1.5;
}
.detailText {
font-size: 9px;
line-height: 9px;
}
}
&.highlighted {
background-color: $fallback--fg;
background-color: var(--selectedMenuPopover, $fallback--fg);
color: var(--selectedMenuPopoverText, $fallback--text);
--faint: var(--selectedMenuPopoverFaintText, $fallback--faint);
--faintLink: var(--selectedMenuPopoverFaintLink, $fallback--faint);
--lightText: var(--selectedMenuPopoverLightText, $fallback--lightText);
--icon: var(--selectedMenuPopoverIcon, $fallback--icon);
}
}
}
</style>
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index a2c99c16c0..ff56d63739 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -1,137 +1,137 @@
<template>
<Popover
+ ref="popover"
trigger="click"
popover-class="emoji-picker popover-default"
- ref="popover"
@show="onPopoverShown"
@close="onPopoverClosed"
>
<template #content>
<div class="heading">
<span
ref="header"
class="emoji-tabs"
>
<span
v-for="group in filteredEmojiGroups"
:ref="setGroupRef('group-header-' + group.id)"
:key="group.id"
class="emoji-tabs-item"
:class="{
active: activeGroupView === group.id
}"
:title="group.text"
@click.prevent="highlight(group.id)"
>
<span
v-if="group.image"
class="emoji-picker-header-image"
>
<still-image
:alt="group.text"
:src="group.image"
/>
</span>
<FAIcon
v-else
:icon="group.icon"
fixed-width
/>
</span>
</span>
<span
v-if="stickerPickerEnabled"
class="additional-tabs"
>
<span
class="stickers-tab-icon additional-tabs-item"
:class="{active: showingStickers}"
:title="$t('emoji.stickers')"
@click.prevent="toggleStickers"
>
<FAIcon
icon="sticky-note"
fixed-width
/>
</span>
</span>
</div>
<div
v-if="contentLoaded"
class="content"
>
<div
class="emoji-content"
:class="{hidden: showingStickers}"
>
<div class="emoji-search">
<input
+ ref="search"
v-model="keyword"
type="text"
class="form-control"
:placeholder="$t('emoji.search_emoji')"
@input="$event.target.composing = false"
- ref="search"
>
</div>
<div
ref="emoji-groups"
class="emoji-groups"
:class="groupsScrolledClass"
@scroll="onScroll"
>
<div
v-for="group in filteredEmojiGroups"
:key="group.id"
class="emoji-group"
>
<h6
:ref="setGroupRef('group-' + group.id)"
class="emoji-group-title"
>
{{ group.text }}
</h6>
<span
v-for="emoji in group.emojis"
:key="group.id + emoji.displayText"
:title="maybeLocalizedEmojiName(emoji)"
class="emoji-item"
@click.stop.prevent="onEmoji(emoji)"
>
<span
v-if="!emoji.imageUrl"
class="emoji-picker-emoji -unicode"
>{{ emoji.replacement }}</span>
<still-image
v-else
:ref="setEmojiRef(group.id + emoji.displayText)"
class="emoji-picker-emoji -custom"
:data-src="emoji.imageUrl"
:data-emoji-name="group.id + emoji.displayText"
/>
</span>
<span :ref="setGroupRef('group-end-' + group.id)" />
</div>
</div>
<div class="keep-open">
<Checkbox v-model="keepOpen">
{{ $t('emoji.keep_open') }}
</Checkbox>
</div>
</div>
<div
v-if="showingStickers"
class="stickers-content"
>
<sticker-picker
@uploaded="onStickerUploaded"
@upload-failed="onStickerUploadFailed"
/>
</div>
</div>
</template>
</Popover>
</template>
<script src="./emoji_picker.js"></script>
<style lang="scss" src="./emoji_picker.scss"></style>
diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue
index 6e732d1f3f..d642008b0f 100644
--- a/src/components/mobile_nav/mobile_nav.vue
+++ b/src/components/mobile_nav/mobile_nav.vue
@@ -1,240 +1,240 @@
<template>
<div
class="MobileNav"
>
<nav
id="nav"
class="mobile-nav"
@click="scrollToTop()"
>
<div class="item">
<button
class="button-unstyled mobile-nav-button"
:title="$t('nav.mobile_sidebar')"
- :aria-expanaded="this.$refs.sideDrawer && !this.$refs.sideDrawer.closed"
+ :aria-expanaded="$refs.sideDrawer && !$refs.sideDrawer.closed"
@click.stop.prevent="toggleMobileSidebar()"
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="bars"
/>
<div
v-if="unreadChatCount && !chatsPinned"
class="alert-dot"
/>
</button>
<NavigationPins class="pins" />
</div> <div class="item right">
<button
v-if="currentUser"
class="button-unstyled mobile-nav-button"
:title="unseenNotificationsCount ? $t('nav.mobile_notifications_unread_active') : $t('nav.mobile_notifications')"
@click.stop.prevent="openMobileNotifications()"
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="bell"
/>
<div
v-if="unseenNotificationsCount"
class="alert-dot"
/>
</button>
</div>
</nav>
<aside
v-if="currentUser"
class="mobile-notifications-drawer"
:class="{ '-closed': !notificationsOpen }"
@touchstart.stop="notificationsTouchStart"
@touchmove.stop="notificationsTouchMove"
>
<div class="mobile-notifications-header">
<span class="title">{{ $t('notifications.notifications') }}</span>
- <span class="spacer"/>
+ <span class="spacer" />
<button
v-if="notificationsAtTop"
class="button-unstyled mobile-nav-button"
:title="$t('general.scroll_to_top')"
@click.stop.prevent="scrollMobileNotificationsToTop"
>
<FALayers class="fa-scale-110 fa-old-padding-layer">
<FAIcon icon="arrow-up" />
<FAIcon
icon="minus"
transform="up-7"
/>
</FALayers>
</button>
<button
class="button-unstyled mobile-nav-button"
:title="$t('nav.mobile_notifications_close')"
@click.stop.prevent="closeMobileNotifications(true)"
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="times"
/>
</button>
</div>
<div
id="mobile-notifications"
- class="mobile-notifications"
ref="mobileNotifications"
+ class="mobile-notifications"
@scroll="onScroll"
/>
</aside>
<SideDrawer
ref="sideDrawer"
:logout="logout"
/>
</div>
</template>
<script src="./mobile_nav.js"></script>
<style lang="scss">
@import '../../_variables.scss';
.MobileNav {
z-index: var(--ZI_navbar);
.mobile-nav {
display: grid;
line-height: var(--navbar-height);
grid-template-rows: 50px;
grid-template-columns: 2fr auto;
width: 100%;
box-sizing: border-box;
a {
color: var(--topBarLink, $fallback--link);
}
}
.mobile-inner-nav {
width: 100%;
display: flex;
align-items: center;
}
.mobile-nav-button {
display: inline-block;
text-align: center;
padding: 0 1em;
position: relative;
cursor: pointer;
}
.site-name {
padding: 0 .3em;
display: inline-block;
}
.item {
/* moslty just to get rid of extra whitespaces */
display: flex;
}
.alert-dot {
border-radius: 100%;
height: 8px;
width: 8px;
position: absolute;
left: calc(50% - 4px);
top: calc(50% - 4px);
margin-left: 6px;
margin-top: -6px;
background-color: $fallback--cRed;
background-color: var(--badgeNotification, $fallback--cRed);
}
.mobile-notifications-drawer {
width: 100%;
height: 100vh;
overflow-x: hidden;
position: fixed;
top: 0;
left: 0;
box-shadow: 1px 1px 4px rgba(0,0,0,.6);
box-shadow: var(--panelShadow);
transition-property: transform;
transition-duration: 0.25s;
transform: translateX(0);
z-index: var(--ZI_navbar);
-webkit-overflow-scrolling: touch;
&.-closed {
transform: translateX(100%);
box-shadow: none;
}
}
.mobile-notifications-header {
display: flex;
align-items: center;
justify-content: space-between;
z-index: calc(var(--ZI_navbar) + 100);
width: 100%;
height: 50px;
line-height: 50px;
position: absolute;
color: var(--topBarText);
background-color: $fallback--fg;
background-color: var(--topBar, $fallback--fg);
box-shadow: 0px 0px 4px rgba(0,0,0,.6);
box-shadow: var(--topBarShadow);
.spacer {
flex: 1;
}
.title {
font-size: 1.3em;
margin-left: 0.6em;
}
}
.pins {
flex: 1;
.pinned-item {
flex-grow: 1;
}
}
.mobile-notifications {
margin-top: 50px;
width: 100vw;
height: calc(100vh - var(--navbar-height));
overflow-x: hidden;
overflow-y: scroll;
color: $fallback--text;
color: var(--text, $fallback--text);
background-color: $fallback--bg;
background-color: var(--bg, $fallback--bg);
.notifications {
padding: 0;
border-radius: 0;
box-shadow: none;
.panel {
border-radius: 0;
margin: 0;
box-shadow: none;
}
.panel::after {
border-radius: 0;
}
.panel .panel-heading {
border-radius: 0;
box-shadow: none;
}
}
}
}
</style>
diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue
index 3d5878d4d5..633efca6b0 100644
--- a/src/components/notifications/notifications.vue
+++ b/src/components/notifications/notifications.vue
@@ -1,101 +1,101 @@
<template>
<teleport
:disabled="minimalMode || disableTeleport"
:to="teleportTarget"
>
<component
:is="noHeading ? 'div' : 'aside'"
ref="root"
:class="{ minimal: minimalMode }"
class="Notifications"
>
<div :class="mainClass">
<div
v-if="!noHeading"
class="notifications-heading panel-heading -sticky"
>
<div class="title">
{{ $t('notifications.notifications') }}
<span
v-if="unseenCount"
class="badge badge-notification unseen-count"
>{{ unseenCount }}</span>
</div>
<div
- class="rightside-button"
v-if="showScrollTop"
+ class="rightside-button"
>
<button
class="button-unstyled scroll-to-top-button"
type="button"
:title="$t('general.scroll_to_top')"
@click="scrollToTop"
>
<FALayers class="fa-scale-110 fa-old-padding-layer">
<FAIcon icon="arrow-up" />
<FAIcon
icon="minus"
transform="up-7"
/>
</FALayers>
</button>
</div>
<button
v-if="unseenCount"
class="button-default read-button"
type="button"
@click.prevent="markAsSeen"
>
{{ $t('notifications.read') }}
</button>
<NotificationFilters class="rightside-button" />
</div>
<div
class="panel-body"
role="feed"
>
<div
v-for="notification in notificationsToDisplay"
:key="notification.id"
role="listitem"
class="notification"
:class="{unseen: !minimalMode && !notification.seen}"
>
<div class="notification-overlay" />
<notification :notification="notification" />
</div>
</div>
<div class="panel-footer">
<div
v-if="bottomedOut"
class="new-status-notification text-center faint"
>
{{ $t('notifications.no_more_notifications') }}
</div>
<button
v-else-if="!loading"
class="button-unstyled -link -fullwidth"
@click.prevent="fetchOlderNotifications()"
>
<div class="new-status-notification text-center">
{{ minimalMode ? $t('interactions.load_older') : $t('notifications.load_older') }}
</div>
</button>
<div
v-else
class="new-status-notification text-center"
>
<FAIcon
icon="circle-notch"
spin
size="lg"
/>
</div>
</div>
</div>
</component>
</teleport>
</template>
<script src="./notifications.js"></script>
<style lang="scss" src="./notifications.scss"></style>
diff --git a/src/components/popover/popover.vue b/src/components/popover/popover.vue
index c2cf23275b..2869d73601 100644
--- a/src/components/popover/popover.vue
+++ b/src/components/popover/popover.vue
@@ -1,210 +1,213 @@
<template>
<span
@mouseenter="onMouseenter"
@mouseleave="onMouseleave"
>
<button
ref="trigger"
class="button-unstyled popover-trigger-button"
type="button"
v-bind="triggerAttrs"
@click="onClick"
>
<slot name="trigger" />
</button>
- <teleport :disabled="!teleport" to="#popovers">
+ <teleport
+ :disabled="!teleport"
+ to="#popovers"
+ >
<transition name="fade">
<div
v-if="!hidden"
ref="content"
:style="styles"
class="popover"
:class="popoverClass || 'popover-default'"
@mouseenter="onMouseenterContent"
@mouseleave="onMouseleaveContent"
@click="onClickContent"
>
<slot
name="content"
class="popover-inner"
:close="hidePopover"
/>
</div>
</transition>
</teleport>
</span>
</template>
<script src="./popover.js" />
<style lang="scss">
@import '../../_variables.scss';
.popover-trigger-button {
display: inline-block;
}
.popover {
z-index: var(--ZI_popover_override, var(--ZI_popovers));
position: fixed;
min-width: 0;
max-width: calc(100vw - 20px);
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
box-shadow: var(--popupShadow);
}
.popover-default {
&:after {
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 3;
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.6);
box-shadow: var(--panelShadow);
pointer-events: none;
}
border-radius: $fallback--btnRadius;
border-radius: var(--btnRadius, $fallback--btnRadius);
background-color: $fallback--bg;
background-color: var(--popover, $fallback--bg);
color: $fallback--text;
color: var(--popoverText, $fallback--text);
--faint: var(--popoverFaintText, $fallback--faint);
--faintLink: var(--popoverFaintLink, $fallback--faint);
--lightText: var(--popoverLightText, $fallback--lightText);
--postLink: var(--popoverPostLink, $fallback--link);
--postFaintLink: var(--popoverPostFaintLink, $fallback--link);
--icon: var(--popoverIcon, $fallback--icon);
}
.dropdown-menu {
display: block;
padding: .5rem 0;
font-size: 1em;
text-align: left;
list-style: none;
max-width: 100vw;
z-index: var(--ZI_popover_override, var(--ZI_popovers));
white-space: nowrap;
.dropdown-divider {
height: 0;
margin: .5rem 0;
overflow: hidden;
border-top: 1px solid $fallback--border;
border-top: 1px solid var(--border, $fallback--border);
}
.dropdown-item {
line-height: 21px;
overflow: hidden;
display: block;
padding: 0.5em 0.75em;
clear: both;
font-weight: 400;
text-align: inherit;
white-space: nowrap;
border: none;
border-radius: 0px;
background-color: transparent;
box-shadow: none;
width: 100%;
height: 100%;
box-sizing: border-box;
--btnText: var(--popoverText, $fallback--text);
&-icon {
svg {
width: 22px;
margin-right: 0.75rem;
color: var(--menuPopoverIcon, $fallback--icon)
}
}
&.-has-submenu {
.chevron-icon {
margin-right: 0.25rem;
margin-left: 2rem;
}
}
&:active, &:hover {
background-color: $fallback--lightBg;
background-color: var(--selectedMenuPopover, $fallback--lightBg);
box-shadow: none;
--btnText: var(--selectedMenuPopoverText, $fallback--link);
--faint: var(--selectedMenuPopoverFaintText, $fallback--faint);
--faintLink: var(--selectedMenuPopoverFaintLink, $fallback--faint);
--lightText: var(--selectedMenuPopoverLightText, $fallback--lightText);
--icon: var(--selectedMenuPopoverIcon, $fallback--icon);
svg {
color: var(--selectedMenuPopoverIcon, $fallback--icon);
--icon: var(--selectedMenuPopoverIcon, $fallback--icon);
}
}
.menu-checkbox {
display: inline-block;
vertical-align: middle;
min-width: 22px;
max-width: 22px;
min-height: 22px;
max-height: 22px;
line-height: 22px;
text-align: center;
border-radius: 0px;
background-color: $fallback--fg;
background-color: var(--input, $fallback--fg);
box-shadow: 0px 0px 2px black inset;
box-shadow: var(--inputShadow);
margin-right: 0.75em;
&.menu-checkbox-checked::after {
font-size: 1.25em;
content: '✓';
}
&.-radio {
border-radius: 9999px;
&.menu-checkbox-checked::after {
font-size: 2em;
content: '•';
}
}
}
}
.button-default.dropdown-item {
&,
i[class*=icon-] {
color: $fallback--text;
color: var(--btnText, $fallback--text);
}
&:active {
background-color: $fallback--lightBg;
background-color: var(--selectedMenuPopover, $fallback--lightBg);
color: $fallback--link;
color: var(--selectedMenuPopoverText, $fallback--link);
}
&:disabled {
color: $fallback--text;
color: var(--btnDisabledText, $fallback--text);
}
&.toggled {
color: $fallback--text;
color: var(--btnToggledText, $fallback--text);
}
}
}
</style>
diff --git a/src/components/quick_filter_settings/quick_filter_settings.vue b/src/components/quick_filter_settings/quick_filter_settings.vue
index 87fcd7167e..f2aa61ee92 100644
--- a/src/components/quick_filter_settings/quick_filter_settings.vue
+++ b/src/components/quick_filter_settings/quick_filter_settings.vue
@@ -1,88 +1,88 @@
<template>
<Popover
trigger="click"
class="QuickFilterSettings"
:bound-to="{ x: 'container' }"
- :triggerAttrs="{ title: $t('timeline.quick_filter_settings') }"
+ :trigger-attrs="{ title: $t('timeline.quick_filter_settings') }"
>
<template #content>
<div class="dropdown-menu">
<div v-if="loggedIn">
<button
v-if="!conversation"
class="button-default dropdown-item"
@click="replyVisibilityAll = true"
>
<span
class="menu-checkbox -radio"
:class="{ 'menu-checkbox-checked': replyVisibilityAll }"
/>{{ $t('settings.reply_visibility_all') }}
</button>
<button
v-if="!conversation"
class="button-default dropdown-item"
@click="replyVisibilityFollowing = true"
>
<span
class="menu-checkbox -radio"
:class="{ 'menu-checkbox-checked': replyVisibilityFollowing }"
/>{{ $t('settings.reply_visibility_following_short') }}
</button>
<button
v-if="!conversation"
class="button-default dropdown-item"
@click="replyVisibilitySelf = true"
>
<span
class="menu-checkbox -radio"
:class="{ 'menu-checkbox-checked': replyVisibilitySelf }"
/>{{ $t('settings.reply_visibility_self_short') }}
</button>
<div
v-if="!conversation"
role="separator"
class="dropdown-divider"
/>
</div>
<button
class="button-default dropdown-item"
@click="muteBotStatuses = !muteBotStatuses"
>
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': muteBotStatuses }"
/>{{ $t('settings.mute_bot_posts') }}
</button>
<button
class="button-default dropdown-item"
@click="hideMedia = !hideMedia"
>
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': hideMedia }"
/>{{ $t('settings.hide_media_previews') }}
</button>
<button
class="button-default dropdown-item"
@click="hideMutedPosts = !hideMutedPosts"
>
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': hideMutedPosts }"
/>{{ $t('settings.hide_all_muted_posts') }}
</button>
<button
class="button-default dropdown-item dropdown-item-icon"
@click="openTab('filtering')"
>
<FAIcon icon="font" />{{ $t('settings.word_filter_and_more') }}
</button>
</div>
</template>
<template #trigger>
<FAIcon icon="filter" />
</template>
</Popover>
</template>
<script src="./quick_filter_settings.js"></script>
diff --git a/src/components/quick_view_settings/quick_view_settings.vue b/src/components/quick_view_settings/quick_view_settings.vue
index d7c9bf3bf3..4bd81c5bd8 100644
--- a/src/components/quick_view_settings/quick_view_settings.vue
+++ b/src/components/quick_view_settings/quick_view_settings.vue
@@ -1,75 +1,75 @@
<template>
<Popover
trigger="click"
class="QuickViewSettings"
:bound-to="{ x: 'container' }"
- :triggerAttrs="{ title: $t('timeline.quick_view_settings') }"
+ :trigger-attrs="{ title: $t('timeline.quick_view_settings') }"
>
<template #content>
<div class="dropdown-menu">
<button
class="button-default dropdown-item"
@click="conversationDisplay = 'tree'"
>
<span
class="menu-checkbox -radio"
:class="{ 'menu-checkbox-checked': conversationDisplay === 'tree' }"
/><FAIcon icon="folder-tree" /> {{ $t('settings.conversation_display_tree_quick') }}
</button>
<button
class="button-default dropdown-item"
@click="conversationDisplay = 'linear'"
>
<span
class="menu-checkbox -radio"
:class="{ 'menu-checkbox-checked': conversationDisplay === 'linear' }"
/><FAIcon icon="list" /> {{ $t('settings.conversation_display_linear_quick') }}
</button>
<div
role="separator"
class="dropdown-divider"
/>
<button
class="button-default dropdown-item"
@click="showUserAvatars = !showUserAvatars"
>
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': showUserAvatars }"
/>{{ $t('settings.mention_link_show_avatar_quick') }}
</button>
<button
v-if="!conversation"
class="button-default dropdown-item"
@click="autoUpdate = !autoUpdate"
>
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': autoUpdate }"
/>{{ $t('settings.auto_update') }}
</button>
<button
v-if="!conversation"
class="button-default dropdown-item"
@click="collapseWithSubjects = !collapseWithSubjects"
>
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': collapseWithSubjects }"
/>{{ $t('settings.collapse_subject') }}
</button>
<button
class="button-default dropdown-item dropdown-item-icon"
@click="openTab('general')"
>
<FAIcon icon="wrench" />{{ $t('settings.more_settings') }}
</button>
</div>
</template>
<template #trigger>
<FAIcon icon="bars" />
</template>
</Popover>
</template>
<script src="./quick_view_settings.js"></script>
diff --git a/src/components/search/search.js b/src/components/search/search.js
index 8d4212cd36..877d6f300f 100644
--- a/src/components/search/search.js
+++ b/src/components/search/search.js
@@ -1,131 +1,131 @@
import FollowCard from '../follow_card/follow_card.vue'
import Conversation from '../conversation/conversation.vue'
import Status from '../status/status.vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
import map from 'lodash/map'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faCircleNotch,
faSearch
} from '@fortawesome/free-solid-svg-icons'
import { uniqBy } from 'lodash'
library.add(
faCircleNotch,
faSearch
)
const Search = {
components: {
FollowCard,
Conversation,
Status,
TabSwitcher
},
props: [
'query'
],
data () {
return {
loaded: false,
loading: false,
searchTerm: this.query || '',
userIds: [],
statuses: [],
hashtags: [],
currenResultTab: 'statuses',
statusesOffset: 0,
lastStatusFetchCount: 0,
lastQuery: ''
}
},
computed: {
users () {
return this.userIds.map(userId => this.$store.getters.findUser(userId))
},
visibleStatuses () {
const allStatusesObject = this.$store.state.statuses.allStatusesObject
return this.statuses.filter(status =>
allStatusesObject[status.id] && !allStatusesObject[status.id].deleted
)
}
},
mounted () {
this.search(this.query)
},
watch: {
query (newValue) {
this.searchTerm = newValue
this.search(newValue)
}
},
methods: {
newQuery (query) {
this.$router.push({ name: 'search', query: { query } })
this.$refs.searchInput.focus()
},
search (query, searchType = null) {
if (!query) {
this.loading = false
return
}
this.loading = true
this.$refs.searchInput.blur()
if (this.lastQuery !== query) {
this.userIds = []
this.hashtags = []
this.statuses = []
this.statusesOffset = 0
this.lastStatusFetchCount = 0
}
- this.$store.dispatch('search', { q: query, resolve: true, offset: this.statusesOffset, 'type': searchType })
+ this.$store.dispatch('search', { q: query, resolve: true, offset: this.statusesOffset, type: searchType })
.then(data => {
this.loading = false
- let oldLength = this.statuses.length
+ const oldLength = this.statuses.length
// Always append to old results. If new results are empty, this doesn't change anything
this.userIds = this.userIds.concat(map(data.accounts, 'id'))
this.statuses = uniqBy(this.statuses.concat(data.statuses), 'id')
this.hashtags = this.hashtags.concat(data.hashtags)
this.currenResultTab = this.getActiveTab()
this.loaded = true
// Offset from whatever we already have
this.statusesOffset = this.statuses.length
// Because the amount of new statuses can actually be zero, compare to old lenght instead
this.lastStatusFetchCount = this.statuses.length - oldLength
this.lastQuery = query
})
},
resultCount (tabName) {
const length = this[tabName].length
return length === 0 ? '' : ` (${length})`
},
onResultTabSwitch (key) {
this.currenResultTab = key
},
getActiveTab () {
if (this.visibleStatuses.length > 0) {
return 'statuses'
} else if (this.users.length > 0) {
return 'people'
} else if (this.hashtags.length > 0) {
return 'hashtags'
}
return 'statuses'
},
lastHistoryRecord (hashtag) {
return hashtag.history && hashtag.history[0]
}
}
}
export default Search
diff --git a/src/components/timeline/timeline.vue b/src/components/timeline/timeline.vue
index 877a0cc080..2279f21a09 100644
--- a/src/components/timeline/timeline.vue
+++ b/src/components/timeline/timeline.vue
@@ -1,151 +1,157 @@
<template>
<div :class="['Timeline', classes.root]">
<div :class="classes.header">
<TimelineMenu
v-if="!embedded"
:timeline-name="timelineName"
/>
<div
- class="rightside-button"
v-if="showScrollTop && !embedded"
+ class="rightside-button"
>
<button
class="button-unstyled scroll-to-top-button"
type="button"
:title="$t('general.scroll_to_top')"
@click="scrollToTop"
>
<FALayers class="fa-scale-110 fa-old-padding-layer">
<FAIcon icon="arrow-up" />
<FAIcon
icon="minus"
transform="up-7"
/>
</FALayers>
</button>
</div>
<template v-if="mobileLayout && !embedded">
<div
- class="rightside-button"
v-if="showLoadButton"
+ class="rightside-button"
>
<button
class="button-unstyled loadmore-button"
:title="loadButtonString"
@click.prevent="showNewStatuses"
>
<FAIcon
fixed-width
icon="circle-plus"
/>
<div class="alert-badge">
{{ mobileLoadButtonString }}
</div>
</button>
</div>
<div
v-else-if="!embedded"
class="loadmore-text faint veryfaint rightside-icon"
:title="$t('timeline.up_to_date')"
:aria-disabled="true"
@click.prevent
>
<FAIcon
fixed-width
icon="check"
/>
</div>
</template>
<template v-else>
<button
v-if="showLoadButton"
class="button-default loadmore-button"
@click.prevent="showNewStatuses"
>
{{ loadButtonString }}
</button>
<div
v-else-if="!embedded"
class="loadmore-text faint"
@click.prevent
>
{{ $t('timeline.up_to_date') }}
</div>
</template>
- <QuickFilterSettings v-if="!embedded" class="rightside-button"/>
- <QuickViewSettings v-if="!embedded" class="rightside-button"/>
+ <QuickFilterSettings
+ v-if="!embedded"
+ class="rightside-button"
+ />
+ <QuickViewSettings
+ v-if="!embedded"
+ class="rightside-button"
+ />
</div>
<div :class="classes.body">
<div
ref="timeline"
class="timeline"
role="feed"
>
<conversation
v-for="statusId in filteredPinnedStatusIds"
:key="statusId + '-pinned'"
role="listitem"
class="status-fadein"
:status-id="statusId"
:collapsable="true"
:pinned-status-ids-object="pinnedStatusIdsObject"
:in-profile="inProfile"
:profile-user-id="userId"
/>
<conversation
v-for="status in filteredVisibleStatuses"
:key="status.id"
role="listitem"
class="status-fadein"
:status-id="status.id"
:collapsable="true"
:in-profile="inProfile"
:profile-user-id="userId"
:virtual-hidden="virtualScrollingEnabled && !statusesToDisplay.includes(status.id)"
/>
</div>
</div>
<div :class="classes.footer">
<teleport
:to="footerSlipgate"
:disabled="!embedded || !footerSlipgate"
>
<div
v-if="count===0"
class="new-status-notification text-center faint"
>
{{ $t('timeline.no_statuses') }}
</div>
<div
v-else-if="bottomedOut"
class="new-status-notification text-center faint"
>
{{ $t('timeline.no_more_statuses') }}
</div>
<button
v-else-if="!timeline.loading"
class="button-unstyled -link"
@click.prevent="fetchOlderStatuses()"
>
<div class="new-status-notification text-center">
{{ $t('timeline.load_older') }}
</div>
</button>
<div
v-else
class="new-status-notification text-center"
>
<FAIcon
icon="circle-notch"
spin
size="lg"
/>
</div>
</teleport>
</div>
</div>
</template>
<script src="./timeline.js"></script>
<style src="./timeline.scss" lang="scss"> </style>

File Metadata

Mime Type
text/x-diff
Expires
Sun, Nov 1, 8:45 PM (15 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1803318
Default Alt Text
(39 KB)

Event Timeline