aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/basic_user_card/basic_user_card.vue1
-rw-r--r--src/components/extra_buttons/extra_buttons.js13
-rw-r--r--src/components/extra_buttons/extra_buttons.vue15
-rw-r--r--src/components/gallery/gallery.vue8
-rw-r--r--src/components/instance_specific_panel/instance_specific_panel.js3
-rw-r--r--src/components/instance_specific_panel/instance_specific_panel.vue8
-rw-r--r--src/components/interactions/interactions.js4
-rw-r--r--src/components/interactions/interactions.vue9
-rw-r--r--src/components/link-preview/link-preview.js14
-rw-r--r--src/components/link-preview/link-preview.vue2
-rw-r--r--src/components/mobile_nav/mobile_nav.js4
-rw-r--r--src/components/mobile_nav/mobile_nav.vue1
-rw-r--r--src/components/mobile_post_status_modal/mobile_post_status_modal.vue11
-rw-r--r--src/components/search/search.js4
-rw-r--r--src/components/search/search.vue11
-rw-r--r--src/components/status/status.js2
-rw-r--r--src/components/tab_switcher/tab_switcher.js32
-rw-r--r--src/components/user_profile/user_profile.js74
-rw-r--r--src/components/user_profile/user_profile.vue29
-rw-r--r--src/components/who_to_follow/who_to_follow.js3
20 files changed, 148 insertions, 100 deletions
diff --git a/src/components/basic_user_card/basic_user_card.vue b/src/components/basic_user_card/basic_user_card.vue
index 568e9359..8a02174e 100644
--- a/src/components/basic_user_card/basic_user_card.vue
+++ b/src/components/basic_user_card/basic_user_card.vue
@@ -87,6 +87,7 @@
&-expanded-content {
flex: 1;
margin-left: 0.7em;
+ min-width: 0;
}
}
</style>
diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js
index 2ec72729..2d05ad39 100644
--- a/src/components/extra_buttons/extra_buttons.js
+++ b/src/components/extra_buttons/extra_buttons.js
@@ -16,6 +16,16 @@ const ExtraButtons = {
this.$store.dispatch('unpinStatus', this.status.id)
.then(() => this.$emit('onSuccess'))
.catch(err => this.$emit('onError', err.error.error))
+ },
+ muteConversation () {
+ this.$store.dispatch('muteConversation', this.status.id)
+ .then(() => this.$emit('onSuccess'))
+ .catch(err => this.$emit('onError', err.error.error))
+ },
+ unmuteConversation () {
+ this.$store.dispatch('unmuteConversation', this.status.id)
+ .then(() => this.$emit('onSuccess'))
+ .catch(err => this.$emit('onError', err.error.error))
}
},
computed: {
@@ -30,9 +40,6 @@ const ExtraButtons = {
},
canPin () {
return this.ownStatus && (this.status.visibility === 'public' || this.status.visibility === 'unlisted')
- },
- enabled () {
- return this.canPin || this.canDelete
}
}
}
diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue
index cdad1666..564d34df 100644
--- a/src/components/extra_buttons/extra_buttons.vue
+++ b/src/components/extra_buttons/extra_buttons.vue
@@ -1,6 +1,5 @@
<template>
<v-popover
- v-if="enabled"
trigger="click"
placement="top"
class="extra-button-popover"
@@ -10,6 +9,20 @@
<div slot="popover">
<div class="dropdown-menu">
<button
+ v-if="!status.muted"
+ class="dropdown-item dropdown-item-icon"
+ @click.prevent="muteConversation"
+ >
+ <i class="icon-eye-off" /><span>{{ $t("status.mute_conversation") }}</span>
+ </button>
+ <button
+ v-if="status.muted"
+ class="dropdown-item dropdown-item-icon"
+ @click.prevent="unmuteConversation"
+ >
+ <i class="icon-eye-off" /><span>{{ $t("status.unmute_conversation") }}</span>
+ </button>
+ <button
v-if="!status.pinned && canPin"
v-close-popover
class="dropdown-item dropdown-item-icon"
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index 6adfb76c..6169d294 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -61,13 +61,17 @@
}
&.contain-fit {
- img, video {
+ img,
+ video,
+ canvas {
object-fit: contain;
}
}
&.cover-fit {
- img, video {
+ img,
+ video,
+ canvas {
object-fit: cover;
}
}
diff --git a/src/components/instance_specific_panel/instance_specific_panel.js b/src/components/instance_specific_panel/instance_specific_panel.js
index 9bb5e945..09e3d055 100644
--- a/src/components/instance_specific_panel/instance_specific_panel.js
+++ b/src/components/instance_specific_panel/instance_specific_panel.js
@@ -2,9 +2,6 @@ const InstanceSpecificPanel = {
computed: {
instanceSpecificPanelContent () {
return this.$store.state.instance.instanceSpecificPanelContent
- },
- show () {
- return !this.$store.state.config.hideISP
}
}
}
diff --git a/src/components/instance_specific_panel/instance_specific_panel.vue b/src/components/instance_specific_panel/instance_specific_panel.vue
index a7cf6b48..7448ca06 100644
--- a/src/components/instance_specific_panel/instance_specific_panel.vue
+++ b/src/components/instance_specific_panel/instance_specific_panel.vue
@@ -1,8 +1,5 @@
<template>
- <div
- v-if="show"
- class="instance-specific-panel"
- >
+ <div class="instance-specific-panel">
<div class="panel panel-default">
<div class="panel-body">
<!-- eslint-disable vue/no-v-html -->
@@ -14,6 +11,3 @@
</template>
<script src="./instance_specific_panel.js" ></script>
-
-<style lang="scss">
-</style>
diff --git a/src/components/interactions/interactions.js b/src/components/interactions/interactions.js
index d4e3cc17..1f8a9de9 100644
--- a/src/components/interactions/interactions.js
+++ b/src/components/interactions/interactions.js
@@ -13,8 +13,8 @@ const Interactions = {
}
},
methods: {
- onModeSwitch (index, dataset) {
- this.filterMode = tabModeDict[dataset.filter]
+ onModeSwitch (key) {
+ this.filterMode = tabModeDict[key]
}
},
components: {
diff --git a/src/components/interactions/interactions.vue b/src/components/interactions/interactions.vue
index d71c99d5..08cee343 100644
--- a/src/components/interactions/interactions.vue
+++ b/src/components/interactions/interactions.vue
@@ -10,18 +10,15 @@
:on-switch="onModeSwitch"
>
<span
- data-tab-dummy
- data-filter="mentions"
+ key="mentions"
:label="$t('nav.mentions')"
/>
<span
- data-tab-dummy
- data-filter="likes+repeats"
+ key="likes+repeats"
:label="$t('interactions.favs_repeats')"
/>
<span
- data-tab-dummy
- data-filter="follows"
+ key="follows"
:label="$t('interactions.follows')"
/>
</tab-switcher>
diff --git a/src/components/link-preview/link-preview.js b/src/components/link-preview/link-preview.js
index 2f6da55e..444aafbe 100644
--- a/src/components/link-preview/link-preview.js
+++ b/src/components/link-preview/link-preview.js
@@ -5,6 +5,11 @@ const LinkPreview = {
'size',
'nsfw'
],
+ data () {
+ return {
+ imageLoaded: false
+ }
+ },
computed: {
useImage () {
// Currently BE shoudn't give cards if tagged NSFW, this is a bit paranoid
@@ -15,6 +20,15 @@ const LinkPreview = {
useDescription () {
return this.card.description && /\S/.test(this.card.description)
}
+ },
+ created () {
+ if (this.useImage) {
+ const newImg = new Image()
+ newImg.onload = () => {
+ this.imageLoaded = true
+ }
+ newImg.src = this.card.image
+ }
}
}
diff --git a/src/components/link-preview/link-preview.vue b/src/components/link-preview/link-preview.vue
index 493774c2..69171977 100644
--- a/src/components/link-preview/link-preview.vue
+++ b/src/components/link-preview/link-preview.vue
@@ -7,7 +7,7 @@
rel="noopener"
>
<div
- v-if="useImage"
+ v-if="useImage && imageLoaded"
class="card-image"
:class="{ 'small-image': size === 'small' }"
>
diff --git a/src/components/mobile_nav/mobile_nav.js b/src/components/mobile_nav/mobile_nav.js
index 9b341a3b..c2bb76ee 100644
--- a/src/components/mobile_nav/mobile_nav.js
+++ b/src/components/mobile_nav/mobile_nav.js
@@ -1,14 +1,12 @@
import SideDrawer from '../side_drawer/side_drawer.vue'
import Notifications from '../notifications/notifications.vue'
-import MobilePostStatusModal from '../mobile_post_status_modal/mobile_post_status_modal.vue'
import { unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils'
import GestureService from '../../services/gesture_service/gesture_service'
const MobileNav = {
components: {
SideDrawer,
- Notifications,
- MobilePostStatusModal
+ Notifications
},
data: () => ({
notificationsCloseGesture: undefined,
diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue
index f67b7ff8..d1c24e56 100644
--- a/src/components/mobile_nav/mobile_nav.vue
+++ b/src/components/mobile_nav/mobile_nav.vue
@@ -70,7 +70,6 @@
ref="sideDrawer"
:logout="logout"
/>
- <MobilePostStatusModal />
</div>
</template>
diff --git a/src/components/mobile_post_status_modal/mobile_post_status_modal.vue b/src/components/mobile_post_status_modal/mobile_post_status_modal.vue
index 5db7584b..b6d7d3ba 100644
--- a/src/components/mobile_post_status_modal/mobile_post_status_modal.vue
+++ b/src/components/mobile_post_status_modal/mobile_post_status_modal.vue
@@ -34,14 +34,19 @@
@import '../../_variables.scss';
.post-form-modal-view {
- max-height: 100%;
- display: block;
+ align-items: flex-start;
}
.post-form-modal-panel {
flex-shrink: 0;
- margin: 25% 0 4em 0;
+ margin-top: 25%;
+ margin-bottom: 2em;
width: 100%;
+ max-width: 700px;
+
+ @media (orientation: landscape) {
+ margin-top: 8%;
+ }
}
.new-status-button {
diff --git a/src/components/search/search.js b/src/components/search/search.js
index b434e127..8e903052 100644
--- a/src/components/search/search.js
+++ b/src/components/search/search.js
@@ -75,8 +75,8 @@ const Search = {
const length = this[tabName].length
return length === 0 ? '' : ` (${length})`
},
- onResultTabSwitch (_index, dataset) {
- this.currenResultTab = dataset.filter
+ onResultTabSwitch (key) {
+ this.currenResultTab = key
},
getActiveTab () {
if (this.visibleStatuses.length > 0) {
diff --git a/src/components/search/search.vue b/src/components/search/search.vue
index 4350e672..746bbaa2 100644
--- a/src/components/search/search.vue
+++ b/src/components/search/search.vue
@@ -31,21 +31,18 @@
<tab-switcher
ref="tabSwitcher"
:on-switch="onResultTabSwitch"
- :custom-active="currenResultTab"
+ :active-tab="currenResultTab"
>
<span
- data-tab-dummy
- data-filter="statuses"
+ key="statuses"
:label="$t('user_card.statuses') + resultCount('visibleStatuses')"
/>
<span
- data-tab-dummy
- data-filter="people"
+ key="people"
:label="$t('search.people') + resultCount('users')"
/>
<span
- data-tab-dummy
- data-filter="hashtags"
+ key="hashtags"
:label="$t('search.hashtags') + resultCount('hashtags')"
/>
</tab-switcher>
diff --git a/src/components/status/status.js b/src/components/status/status.js
index 3c172e5b..502d9583 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -335,7 +335,7 @@ const Status = {
return
}
}
- if (target.className.match(/hashtag/)) {
+ if (target.rel.match(/(?:^|\s)tag(?:$|\s)/) || target.className.match(/hashtag/)) {
// Extract tag name from link url
const tag = extractTagFromUrl(target.href)
if (tag) {
diff --git a/src/components/tab_switcher/tab_switcher.js b/src/components/tab_switcher/tab_switcher.js
index a5fe019c..08d5d08f 100644
--- a/src/components/tab_switcher/tab_switcher.js
+++ b/src/components/tab_switcher/tab_switcher.js
@@ -4,12 +4,22 @@ import './tab_switcher.scss'
export default Vue.component('tab-switcher', {
name: 'TabSwitcher',
- props: ['renderOnlyFocused', 'onSwitch', 'customActive'],
+ props: ['renderOnlyFocused', 'onSwitch', 'activeTab'],
data () {
return {
active: this.$slots.default.findIndex(_ => _.tag)
}
},
+ computed: {
+ activeIndex () {
+ // In case of controlled component
+ if (this.activeTab) {
+ return this.$slots.default.findIndex(slot => this.activeTab === slot.key)
+ } else {
+ return this.active
+ }
+ }
+ },
beforeUpdate () {
const currentSlot = this.$slots.default[this.active]
if (!currentSlot.tag) {
@@ -17,21 +27,13 @@ export default Vue.component('tab-switcher', {
}
},
methods: {
- activateTab (index, dataset) {
+ activateTab (index) {
return () => {
if (typeof this.onSwitch === 'function') {
- this.onSwitch.call(null, index, this.$slots.default[index].elm.dataset)
+ this.onSwitch.call(null, this.$slots.default[index].key)
}
this.active = index
}
- },
- isActiveTab (index) {
- const customActiveIndex = this.$slots.default.findIndex(slot => {
- const dataFilter = slot.data && slot.data.attrs && slot.data.attrs['data-filter']
- return this.customActive && this.customActive === dataFilter
- })
-
- return customActiveIndex > -1 ? customActiveIndex === index : index === this.active
}
},
render (h) {
@@ -41,13 +43,13 @@ export default Vue.component('tab-switcher', {
const classesTab = ['tab']
const classesWrapper = ['tab-wrapper']
- if (this.isActiveTab(index)) {
+ if (this.activeIndex === index) {
classesTab.push('active')
classesWrapper.push('active')
}
if (slot.data.attrs.image) {
return (
- <div class={ classesWrapper.join(' ')}>
+ <div class={classesWrapper.join(' ')}>
<button
disabled={slot.data.attrs.disabled}
onClick={this.activateTab(index)}
@@ -59,7 +61,7 @@ export default Vue.component('tab-switcher', {
)
}
return (
- <div class={ classesWrapper.join(' ')}>
+ <div class={classesWrapper.join(' ')}>
<button
disabled={slot.data.attrs.disabled}
onClick={this.activateTab(index)}
@@ -71,7 +73,7 @@ export default Vue.component('tab-switcher', {
const contents = this.$slots.default.map((slot, index) => {
if (!slot.tag) return
- const active = index === this.active
+ const active = this.activeIndex === index
if (this.renderOnlyFocused) {
return active
? <div class="active">{slot}</div>
diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index 39b99dac..00055707 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -22,21 +22,23 @@ const FriendList = withLoadMore({
additionalPropNames: ['userId']
})(List)
+const defaultTabKey = 'statuses'
+
const UserProfile = {
data () {
return {
error: false,
- userId: null
+ userId: null,
+ tab: defaultTabKey
}
},
created () {
- // Make sure that timelines used in this page are empty
- this.cleanUp()
const routeParams = this.$route.params
this.load(routeParams.name || routeParams.id)
+ this.tab = get(this.$route, 'query.tab', defaultTabKey)
},
destroyed () {
- this.cleanUp()
+ this.stopFetching()
},
computed: {
timeline () {
@@ -67,17 +69,36 @@ const UserProfile = {
},
methods: {
load (userNameOrId) {
+ const startFetchingTimeline = (timeline, userId) => {
+ // Clear timeline only if load another user's profile
+ if (userId !== this.$store.state.statuses.timelines[timeline].userId) {
+ this.$store.commit('clearTimeline', { timeline })
+ }
+ this.$store.dispatch('startFetchingTimeline', { timeline, userId })
+ }
+
+ const loadById = (userId) => {
+ this.userId = userId
+ startFetchingTimeline('user', userId)
+ startFetchingTimeline('media', userId)
+ if (this.isUs) {
+ startFetchingTimeline('favorites', userId)
+ }
+ // Fetch all pinned statuses immediately
+ this.$store.dispatch('fetchPinnedStatuses', userId)
+ }
+
+ // Reset view
+ this.userId = null
+ this.error = false
+
// Check if user data is already loaded in store
const user = this.$store.getters.findUser(userNameOrId)
if (user) {
- this.userId = user.id
- this.fetchTimelines()
+ loadById(user.id)
} else {
this.$store.dispatch('fetchUser', userNameOrId)
- .then(({ id }) => {
- this.userId = id
- this.fetchTimelines()
- })
+ .then(({ id }) => loadById(id))
.catch((reason) => {
const errorMessage = get(reason, 'error.error')
if (errorMessage === 'No user with such user_id') { // Known error
@@ -90,40 +111,33 @@ const UserProfile = {
})
}
},
- fetchTimelines () {
- const userId = this.userId
- this.$store.dispatch('startFetchingTimeline', { timeline: 'user', userId })
- this.$store.dispatch('startFetchingTimeline', { timeline: 'media', userId })
- if (this.isUs) {
- this.$store.dispatch('startFetchingTimeline', { timeline: 'favorites', userId })
- }
- // Fetch all pinned statuses immediately
- this.$store.dispatch('fetchPinnedStatuses', userId)
- },
- cleanUp () {
+ stopFetching () {
this.$store.dispatch('stopFetching', 'user')
this.$store.dispatch('stopFetching', 'favorites')
this.$store.dispatch('stopFetching', 'media')
- this.$store.commit('clearTimeline', { timeline: 'user' })
- this.$store.commit('clearTimeline', { timeline: 'favorites' })
- this.$store.commit('clearTimeline', { timeline: 'media' })
+ },
+ switchUser (userNameOrId) {
+ this.stopFetching()
+ this.load(userNameOrId)
+ },
+ onTabSwitch (tab) {
+ this.tab = tab
+ this.$router.replace({ query: { tab } })
}
},
watch: {
'$route.params.id': function (newVal) {
if (newVal) {
- this.cleanUp()
- this.load(newVal)
+ this.switchUser(newVal)
}
},
'$route.params.name': function (newVal) {
if (newVal) {
- this.cleanUp()
- this.load(newVal)
+ this.switchUser(newVal)
}
},
- $route () {
- this.$refs.tabSwitcher.activateTab(0)()
+ '$route.query': function (newVal) {
+ this.tab = newVal.tab || defaultTabKey
}
},
components: {
diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue
index cffa28f1..42516916 100644
--- a/src/components/user_profile/user_profile.vue
+++ b/src/components/user_profile/user_profile.vue
@@ -12,22 +12,24 @@
rounded="top"
/>
<tab-switcher
- ref="tabSwitcher"
+ :active-tab="tab"
:render-only-focused="true"
+ :on-switch="onTabSwitch"
>
- <div :label="$t('user_card.statuses')">
- <Timeline
- :count="user.statuses_count"
- :embedded="true"
- :title="$t('user_profile.timeline_title')"
- :timeline="timeline"
- timeline-name="user"
- :user-id="userId"
- :pinned-status-ids="user.pinnedStatusIds"
- />
- </div>
+ <Timeline
+ key="statuses"
+ :label="$t('user_card.statuses')"
+ :count="user.statuses_count"
+ :embedded="true"
+ :title="$t('user_profile.timeline_title')"
+ :timeline="timeline"
+ timeline-name="user"
+ :user-id="userId"
+ :pinned-status-ids="user.pinnedStatusIds"
+ />
<div
v-if="followsTabVisible"
+ key="followees"
:label="$t('user_card.followees')"
:disabled="!user.friends_count"
>
@@ -42,6 +44,7 @@
</div>
<div
v-if="followersTabVisible"
+ key="followers"
:label="$t('user_card.followers')"
:disabled="!user.followers_count"
>
@@ -58,6 +61,7 @@
</FollowerList>
</div>
<Timeline
+ key="media"
:label="$t('user_card.media')"
:disabled="!media.visibleStatuses.length"
:embedded="true"
@@ -68,6 +72,7 @@
/>
<Timeline
v-if="isUs"
+ key="favorites"
:label="$t('user_card.favorites')"
:disabled="!favorites.visibleStatuses.length"
:embedded="true"
diff --git a/src/components/who_to_follow/who_to_follow.js b/src/components/who_to_follow/who_to_follow.js
index f8100257..8fab6c4d 100644
--- a/src/components/who_to_follow/who_to_follow.js
+++ b/src/components/who_to_follow/who_to_follow.js
@@ -21,7 +21,8 @@ const WhoToFollow = {
name: i.display_name,
screen_name: i.acct,
profile_image_url: i.avatar || '/images/avi.png',
- profile_image_url_original: i.avatar || '/images/avi.png'
+ profile_image_url_original: i.avatar || '/images/avi.png',
+ statusnet_profile_url: i.url
}
this.users.push(user)