diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js
index ea46ce6f6..e07bb7a25 100644
--- a/build/webpack.base.conf.js
+++ b/build/webpack.base.conf.js
@@ -95,7 +95,8 @@ module.exports = {
},
plugins: [
new ServiceWorkerWebpackPlugin({
- entry: path.join(__dirname, '..', 'src/sw.js')
+ entry: path.join(__dirname, '..', 'src/sw.js'),
+ filename: 'sw-pleroma.js'
})
]
}
diff --git a/src/App.js b/src/App.js
index 85df94169..18bff2dde 100644
--- a/src/App.js
+++ b/src/App.js
@@ -6,6 +6,7 @@ import InstanceSpecificPanel from './components/instance_specific_panel/instance
import FeaturesPanel from './components/features_panel/features_panel.vue'
import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue'
import ChatPanel from './components/chat_panel/chat_panel.vue'
+import MediaModal from './components/media_modal/media_modal.vue'
import SideDrawer from './components/side_drawer/side_drawer.vue'
import { unseenNotificationsFromStore } from './services/notification_utils/notification_utils'
@@ -20,6 +21,7 @@ export default {
FeaturesPanel,
WhoToFollowPanel,
ChatPanel,
+ MediaModal,
SideDrawer
},
data: () => ({
@@ -79,7 +81,8 @@ export default {
},
unseenNotificationsCount () {
return this.unseenNotifications.length
- }
+ },
+ showFeaturesPanel () { return this.$store.state.config.showFeaturesPanel }
},
methods: {
scrollToTop () {
diff --git a/src/App.scss b/src/App.scss
index ed06bbbc1..1eaed6eac 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -425,6 +425,12 @@ main-router {
border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;
border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);
+
+ .faint {
+ color: $fallback--faint;
+ color: var(--panelFaint, $fallback--faint);
+ }
+
a {
color: $fallback--link;
color: var(--panelLink, $fallback--link)
@@ -499,7 +505,7 @@ nav {
}
.main {
- flex-basis: 60%;
+ flex-basis: 50%;
flex-grow: 1;
flex-shrink: 1;
}
@@ -533,7 +539,7 @@ nav {
}
}
-@media all and (min-width: 960px) {
+@media all and (min-width: 800px) {
body {
overflow-y: scroll;
}
@@ -617,7 +623,7 @@ nav {
color: $fallback--faint;
color: var(--faint, $fallback--faint);
}
-@media all and (min-width: 959px) {
+@media all and (min-width: 800px) {
.logo {
opacity: 1 !important;
}
@@ -654,7 +660,34 @@ nav {
border-radius: var(--inputRadius, $fallback--inputRadius);
}
-@media all and (max-width: 959px) {
+@keyframes shakeError {
+ 0% {
+ transform: translateX(0);
+ }
+ 15% {
+ transform: translateX(0.375rem);
+ }
+ 30% {
+ transform: translateX(-0.375rem);
+ }
+ 45% {
+ transform: translateX(0.375rem);
+ }
+ 60% {
+ transform: translateX(-0.375rem);
+ }
+ 75% {
+ transform: translateX(0.375rem);
+ }
+ 90% {
+ transform: translateX(-0.375rem);
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+
+@media all and (max-width: 800px) {
.mobile-hidden {
display: none;
}
@@ -686,3 +719,17 @@ nav {
margin-right: 0.8em;
}
}
+
+.login-hint {
+ text-align: center;
+
+ @media all and (min-width: 801px) {
+ display: none;
+ }
+
+ a {
+ display: inline-block;
+ padding: 1em 0px;
+ width: 100%;
+ }
+}
diff --git a/src/App.vue b/src/App.vue
index feadb009b..7541928f1 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -29,7 +29,7 @@
{{ charactersLeft }}
{{ charactersLeft }}
diff --git a/src/components/registration/registration.vue b/src/components/registration/registration.vue index 25c1a9d0a..f428ead3d 100644 --- a/src/components/registration/registration.vue +++ b/src/components/registration/registration.vue @@ -147,24 +147,6 @@ $validations-cRed: #f04124; margin-bottom: 1em; } - @keyframes shakeError { - 0% { - transform: translateX(0); } - 15% { - transform: translateX(0.375rem); } - 30% { - transform: translateX(-0.375rem); } - 45% { - transform: translateX(0.375rem); } - 60% { - transform: translateX(-0.375rem); } - 75% { - transform: translateX(0.375rem); } - 90% { - transform: translateX(-0.375rem); } - 100% { - transform: translateX(0); } } - .form-group--error { animation-name: shakeError; animation-duration: .6s; @@ -215,7 +197,7 @@ $validations-cRed: #f04124; } } -@media all and (max-width: 959px) { +@media all and (max-width: 800px) { .registration-form .container { flex-direction: column-reverse; } diff --git a/src/components/settings/settings.js b/src/components/settings/settings.js index d45ec72d1..9f2a1de43 100644 --- a/src/components/settings/settings.js +++ b/src/components/settings/settings.js @@ -1,5 +1,5 @@ /* eslint-env browser */ -import TabSwitcher from '../tab_switcher/tab_switcher.jsx' +import TabSwitcher from '../tab_switcher/tab_switcher.js' import StyleSwitcher from '../style_switcher/style_switcher.vue' import InterfaceLanguageSwitcher from '../interface_language_switcher/interface_language_switcher.vue' import { filter, trim } from 'lodash' @@ -13,6 +13,7 @@ const settings = { hideAttachmentsLocal: user.hideAttachments, hideAttachmentsInConvLocal: user.hideAttachmentsInConv, hideNsfwLocal: user.hideNsfw, + useOneClickNsfw: user.useOneClickNsfw, hideISPLocal: user.hideISP, preloadImage: user.preloadImage, @@ -29,7 +30,6 @@ const settings = { notificationVisibilityLocal: user.notificationVisibility, replyVisibilityLocal: user.replyVisibility, loopVideoLocal: user.loopVideo, - loopVideoSilentOnlyLocal: user.loopVideoSilentOnly, muteWordsString: user.muteWords.join('\n'), autoLoadLocal: user.autoLoad, streamingLocal: user.streaming, @@ -46,6 +46,11 @@ const settings = { : user.subjectLineBehavior, subjectLineBehaviorDefault: instance.subjectLineBehavior, + postContentTypeLocal: typeof user.postContentType === 'undefined' + ? instance.postContentType + : user.postContentType, + postContentTypeDefault: instance.postContentType, + alwaysShowSubjectInputLocal: typeof user.alwaysShowSubjectInput === 'undefined' ? instance.alwaysShowSubjectInput : user.alwaysShowSubjectInput, @@ -58,13 +63,16 @@ const settings = { stopGifs: user.stopGifs, webPushNotificationsLocal: user.webPushNotifications, + loopVideoSilentOnlyLocal: user.loopVideosSilentOnly, loopSilentAvailable: // Firefox Object.getOwnPropertyDescriptor(HTMLVideoElement.prototype, 'mozHasAudio') || // Chrome-likes Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'webkitAudioDecodedByteCount') || // Future spec, still not supported in Nightly 63 as of 08/2018 - Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'audioTracks') + Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'audioTracks'), + playVideosInModal: user.playVideosInModal, + useContainFit: user.useContainFit } }, components: { @@ -96,6 +104,9 @@ const settings = { hideNsfwLocal (value) { this.$store.dispatch('setOption', { name: 'hideNsfw', value }) }, + useOneClickNsfw (value) { + this.$store.dispatch('setOption', { name: 'useOneClickNsfw', value }) + }, preloadImage (value) { this.$store.dispatch('setOption', { name: 'preloadImage', value }) }, @@ -151,12 +162,21 @@ const settings = { subjectLineBehaviorLocal (value) { this.$store.dispatch('setOption', { name: 'subjectLineBehavior', value }) }, + postContentTypeLocal (value) { + this.$store.dispatch('setOption', { name: 'postContentType', value }) + }, stopGifs (value) { this.$store.dispatch('setOption', { name: 'stopGifs', value }) }, webPushNotificationsLocal (value) { this.$store.dispatch('setOption', { name: 'webPushNotifications', value }) if (value) this.$store.dispatch('registerPushNotifications') + }, + playVideosInModal (value) { + this.$store.dispatch('setOption', { name: 'playVideosInModal', value }) + }, + useContainFit (value) { + this.$store.dispatch('setOption', { name: 'useContainFit', value }) } } } diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue index 391250096..ba5394896 100644 --- a/src/components/settings/settings.vue +++ b/src/components/settings/settings.vue @@ -100,6 +100,28 @@ 20
},
+ longSubject () {
+ return this.status.summary.length > 900
+ },
isReply () {
- return !!this.status.in_reply_to_status_id
+ return !!(this.status.in_reply_to_status_id && this.status.in_reply_to_user_id)
},
replyToName () {
const user = this.$store.state.users.usersObject[this.status.in_reply_to_user_id]
@@ -178,7 +188,7 @@ const Status = {
return this.tallStatus
},
showingMore () {
- return this.showingTall || (this.status.summary && this.expandingSubject)
+ return (this.tallStatus && this.showingTall) || (this.status.summary && this.expandingSubject)
},
nsfwClickthrough () {
if (!this.status.nsfw) {
@@ -205,12 +215,31 @@ const Status = {
},
attachmentSize () {
if ((this.$store.state.config.hideAttachments && !this.inConversation) ||
- (this.$store.state.config.hideAttachmentsInConv && this.inConversation)) {
+ (this.$store.state.config.hideAttachmentsInConv && this.inConversation) ||
+ (this.status.attachments.length > this.maxAttachments)) {
return 'hide'
} else if (this.compact) {
return 'small'
}
return 'normal'
+ },
+ galleryTypes () {
+ if (this.attachmentSize === 'hide') {
+ return []
+ }
+ return this.$store.state.config.playVideosInModal
+ ? ['image', 'video']
+ : ['image']
+ },
+ galleryAttachments () {
+ return this.status.attachments.filter(
+ file => fileType.fileMatchesSomeType(this.galleryTypes, file)
+ )
+ },
+ nonGalleryAttachments () {
+ return this.status.attachments.filter(
+ file => !fileType.fileMatchesSomeType(this.galleryTypes, file)
+ )
}
},
components: {
@@ -220,7 +249,9 @@ const Status = {
DeleteButton,
PostStatusForm,
UserCardContent,
- StillImage
+ UserAvatar,
+ Gallery,
+ LinkPreview
},
methods: {
visibilityIcon (visibility) {
@@ -235,11 +266,23 @@ const Status = {
return 'icon-globe'
}
},
- linkClicked ({target}) {
+ linkClicked (event) {
+ let { target } = event
if (target.tagName === 'SPAN') {
target = target.parentNode
}
if (target.tagName === 'A') {
+ if (target.className.match(/mention/)) {
+ const href = target.getAttribute('href')
+ const attn = this.status.attentions.find(attn => mentionMatchesUrl(attn, href))
+ if (attn) {
+ event.stopPropagation()
+ event.preventDefault()
+ const link = this.generateUserProfileLink(attn.id, attn.screen_name)
+ this.$router.push(link)
+ return
+ }
+ }
window.open(target.href, '_blank')
}
},
@@ -264,11 +307,11 @@ const Status = {
toggleShowMore () {
if (this.showingTall) {
this.showingTall = false
- } else if (this.expandingSubject) {
+ } else if (this.expandingSubject && this.status.summary) {
this.expandingSubject = false
} else if (this.hideTallStatus) {
this.showingTall = true
- } else if (this.hideSubjectStatus) {
+ } else if (this.hideSubjectStatus && this.status.summary) {
this.expandingSubject = true
}
},
@@ -295,6 +338,10 @@ const Status = {
},
generateUserProfileLink (id, name) {
return generateProfileLink(id, name, this.$store.state.instance.restrictedNicknames)
+ },
+ setMedia () {
+ const attachments = this.attachmentSize === 'hide' ? this.status.attachments : this.galleryAttachments
+ return () => this.$store.dispatch('setMedia', attachments)
}
},
watch: {
@@ -302,8 +349,13 @@ const Status = {
if (this.status.id === id) {
let rect = this.$el.getBoundingClientRect()
if (rect.top < 100) {
- window.scrollBy(0, rect.top - 200)
+ // 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)
}
}
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 5c956467e..21eb4d56f 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -13,10 +13,12 @@
{{ $t('user_card.statuses') }}
- {{user.statuses_count}}
+ {{user.statuses_count}}
{{ $t('user_card.followees') }}
- {{user.friends_count}}
+ {{user.friends_count}}
{{ $t('user_card.followers') }}
- {{user.followers_count}}
+ {{user.followers_count}}