diff --git a/config/index.js b/config/index.js index 5d2cb833..7b0ef26c 100644 --- a/config/index.js +++ b/config/index.js @@ -27,6 +27,11 @@ module.exports = { changeOrigin: true, cookieDomainRewrite: 'localhost' }, + '/nodeinfo': { + target: 'http://localhost:4000/', + changeOrigin: true, + cookieDomainRewrite: 'localhost' + }, '/socket': { target: 'http://localhost:4000/', changeOrigin: true, diff --git a/src/App.js b/src/App.js index c455c18c..05e3eda3 100644 --- a/src/App.js +++ b/src/App.js @@ -2,8 +2,9 @@ import UserPanel from './components/user_panel/user_panel.vue' import NavPanel from './components/nav_panel/nav_panel.vue' import Notifications from './components/notifications/notifications.vue' import UserFinder from './components/user_finder/user_finder.vue' -import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue' import InstanceSpecificPanel from './components/instance_specific_panel/instance_specific_panel.vue' +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' export default { @@ -13,8 +14,9 @@ export default { NavPanel, Notifications, UserFinder, - WhoToFollowPanel, InstanceSpecificPanel, + FeaturesPanel, + WhoToFollowPanel, ChatPanel }, data: () => ({ @@ -34,9 +36,9 @@ export default { computed: { currentUser () { return this.$store.state.users.currentUser }, background () { - return this.currentUser.background_image || this.$store.state.config.background + return this.currentUser.background_image || this.$store.state.instance.background }, - enableMask () { return this.supportsMask && this.$store.state.config.logoMask }, + enableMask () { return this.supportsMask && this.$store.state.instance.logoMask }, logoStyle () { return { 'visibility': this.enableMask ? 'hidden' : 'visible' @@ -44,24 +46,24 @@ export default { }, logoMaskStyle () { return this.enableMask ? { - 'mask-image': `url(${this.$store.state.config.logo})` + 'mask-image': `url(${this.$store.state.instance.logo})` } : { 'background-color': this.enableMask ? '' : 'transparent' } }, logoBgStyle () { return Object.assign({ - 'margin': `${this.$store.state.config.logoMargin} 0` + 'margin': `${this.$store.state.instance.logoMargin} 0` }, this.enableMask ? {} : { 'background-color': this.enableMask ? '' : 'transparent' }) }, - logo () { return this.$store.state.config.logo }, + logo () { return this.$store.state.instance.logo }, style () { return { 'background-image': `url(${this.background})` } }, - sitename () { return this.$store.state.config.name }, + sitename () { return this.$store.state.instance.name }, chat () { return this.$store.state.chat.channel.state === 'joined' }, - suggestionsEnabled () { return this.$store.state.config.suggestionsEnabled }, - showInstanceSpecificPanel () { return this.$store.state.config.showInstanceSpecificPanel } + suggestionsEnabled () { return this.$store.state.instance.suggestionsEnabled }, + showInstanceSpecificPanel () { return this.$store.state.instance.showInstanceSpecificPanel } }, methods: { activatePanel (panelName) { diff --git a/src/App.scss b/src/App.scss index dd43c5ca..056a235e 100644 --- a/src/App.scss +++ b/src/App.scss @@ -248,6 +248,7 @@ nav { justify-content: center; flex: 0 0 auto; z-index: -1; + .mask { mask-repeat: no-repeat; mask-position: center; @@ -260,7 +261,10 @@ nav { left: 0; right: 0; } + img { + height: 100%; + object-fit: contain; display: block; flex: 0; } @@ -325,18 +329,35 @@ main-router { background-size: cover; padding: .6em .6em; text-align: left; - font-size: 1.3em; - line-height: 24px; + line-height: 28px; background-color: $fallback--btn; background-color: var(--btn, $fallback--btn); align-items: baseline; .title { flex: 1 0 auto; + font-size: 1.3em; + } + + .alert { + white-space: nowrap; + text-overflow: ellipsis; + overflow-x: hidden; } button { - height: 100%; + flex-shrink: 0; + } + + button, .alert { + // height: 100%; + line-height: 21px; + min-height: 0; + box-sizing: border-box; + margin: 0; + margin-left: .25em; + min-width: 1px; + align-self: stretch; } } diff --git a/src/App.vue b/src/App.vue index fc446c57..059460f9 100644 --- a/src/App.vue +++ b/src/App.vue @@ -28,6 +28,7 @@ + diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue index e41929fd..5528fef6 100644 --- a/src/components/conversation/conversation.vue +++ b/src/components/conversation/conversation.vue @@ -3,7 +3,7 @@
{{ $t('timeline.conversation') }} - {{ $t('timeline.collapse') }} + {{ $t('timeline.collapse') }}
diff --git a/src/components/favorite_button/favorite_button.js b/src/components/favorite_button/favorite_button.js index 80893719..1621341e 100644 --- a/src/components/favorite_button/favorite_button.js +++ b/src/components/favorite_button/favorite_button.js @@ -2,7 +2,9 @@ const FavoriteButton = { props: ['status', 'loggedIn'], data () { return { - hidePostStatsLocal: this.$store.state.config.hidePostStats, + hidePostStatsLocal: typeof this.$store.state.config.hidePostStats == 'undefined' + ? this.$store.state.instance.hidePostStats + : this.$store.state.config.hidePostStats, animated: false } }, diff --git a/src/components/features_panel/features_panel.js b/src/components/features_panel/features_panel.js new file mode 100644 index 00000000..e0b7a118 --- /dev/null +++ b/src/components/features_panel/features_panel.js @@ -0,0 +1,14 @@ +const FeaturesPanel = { + computed: { + chat: function () { + return this.$store.state.instance.chatAvailable && (!this.$store.state.chatDisabled) + }, + gopher: function () { return this.$store.state.instance.gopherAvailable }, + whoToFollow: function () { return this.$store.state.instance.suggestionsEnabled }, + mediaProxy: function () { return this.$store.state.instance.mediaProxyAvailable }, + scopeOptions: function () { return this.$store.state.instance.scopeOptionsEnabled }, + textlimit: function () { return this.$store.state.instance.textlimit } + } +} + +export default FeaturesPanel diff --git a/src/components/features_panel/features_panel.vue b/src/components/features_panel/features_panel.vue new file mode 100644 index 00000000..445143e9 --- /dev/null +++ b/src/components/features_panel/features_panel.vue @@ -0,0 +1,29 @@ + + + + + diff --git a/src/components/instance_specific_panel/instance_specific_panel.js b/src/components/instance_specific_panel/instance_specific_panel.js index abd408c8..09e3d055 100644 --- a/src/components/instance_specific_panel/instance_specific_panel.js +++ b/src/components/instance_specific_panel/instance_specific_panel.js @@ -1,7 +1,7 @@ const InstanceSpecificPanel = { computed: { instanceSpecificPanelContent () { - return this.$store.state.config.instanceSpecificPanelContent + return this.$store.state.instance.instanceSpecificPanelContent } } } diff --git a/src/components/login_form/login_form.js b/src/components/login_form/login_form.js index a117b76f..4405fb92 100644 --- a/src/components/login_form/login_form.js +++ b/src/components/login_form/login_form.js @@ -5,7 +5,7 @@ const LoginForm = { }), computed: { loggingIn () { return this.$store.state.users.loggingIn }, - registrationOpen () { return this.$store.state.config.registrationOpen } + registrationOpen () { return this.$store.state.instance.registrationOpen } }, methods: { submit () { diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss index 4dbceede..a137ccd5 100644 --- a/src/components/notifications/notifications.scss +++ b/src/components/notifications/notifications.scss @@ -22,10 +22,6 @@ } .loadmore-error { - min-width: 6em; - text-align: center; - padding: 0 0.25em 0 0.25em; - margin: 0; color: $fallback--fg; color: var(--fg, $fallback--fg); } diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index d7f1ffb2..a84e764c 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -75,8 +75,11 @@ const PostStatusForm = { candidates () { const firstchar = this.textAtCaret.charAt(0) if (firstchar === '@') { - const matchedUsers = filter(this.users, (user) => (String(user.name + user.screen_name)).toUpperCase() - .startsWith(this.textAtCaret.slice(1).toUpperCase())) + const query = this.textAtCaret.slice(1).toUpperCase() + const matchedUsers = filter(this.users, (user) => { + return user.screen_name.toUpperCase().startsWith(query) || + user.name && user.name.toUpperCase().startsWith(query) + }) if (matchedUsers.length <= 0) { return false } @@ -99,7 +102,7 @@ const PostStatusForm = { name: '', utf: utf || '', // eslint-disable-next-line camelcase - img: utf ? '' : this.$store.state.config.server + image_url, + img: utf ? '' : this.$store.state.instance.server + image_url, highlighted: index === this.highlighted })) } else { @@ -117,16 +120,16 @@ const PostStatusForm = { return this.$store.state.users.users }, emoji () { - return this.$store.state.config.emoji || [] + return this.$store.state.instance.emoji || [] }, customEmoji () { - return this.$store.state.config.customEmoji || [] + return this.$store.state.instance.customEmoji || [] }, statusLength () { return this.newStatus.status.length }, statusLengthLimit () { - return this.$store.state.config.textlimit + return this.$store.state.instance.textlimit }, hasStatusLengthLimit () { return this.statusLengthLimit > 0 @@ -138,10 +141,10 @@ const PostStatusForm = { return this.hasStatusLengthLimit && (this.statusLength > this.statusLengthLimit) }, scopeOptionsEnabled () { - return this.$store.state.config.scopeOptionsEnabled + return this.$store.state.instance.scopeOptionsEnabled }, formattingOptionsEnabled () { - return this.$store.state.config.formattingOptionsEnabled + return this.$store.state.instance.formattingOptionsEnabled } }, methods: { diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 559ad016..42e9c65c 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -90,8 +90,7 @@
- - +
diff --git a/src/components/registration/registration.js b/src/components/registration/registration.js index 73840608..8f59878d 100644 --- a/src/components/registration/registration.js +++ b/src/components/registration/registration.js @@ -5,16 +5,16 @@ const registration = { registering: false }), created () { - if ((!this.$store.state.config.registrationOpen && !this.token) || !!this.$store.state.users.currentUser) { + if ((!this.$store.state.instance.registrationOpen && !this.token) || !!this.$store.state.users.currentUser) { this.$router.push('/main/all') } // Seems like this doesn't work at first page open for some reason - if (this.$store.state.config.registrationOpen && this.token) { + if (this.$store.state.instance.registrationOpen && this.token) { this.$router.push('/registration') } }, computed: { - termsofservice () { return this.$store.state.config.tos }, + termsofservice () { return this.$store.state.instance.tos }, token () { return this.$route.params.token } }, methods: { diff --git a/src/components/retweet_button/retweet_button.js b/src/components/retweet_button/retweet_button.js index ef2f271a..1527afc8 100644 --- a/src/components/retweet_button/retweet_button.js +++ b/src/components/retweet_button/retweet_button.js @@ -2,7 +2,9 @@ const RetweetButton = { props: ['status', 'loggedIn', 'visibility'], data () { return { - hidePostStatsLocal: this.$store.state.config.hidePostStats, + hidePostStatsLocal: typeof this.$store.state.config.hidePostStats == 'undefined' + ? this.$store.state.instance.hidePostStats + : this.$store.state.config.hidePostStats, animated: false } }, diff --git a/src/components/settings/settings.js b/src/components/settings/settings.js index 1dd53ab2..fe8a2d9e 100644 --- a/src/components/settings/settings.js +++ b/src/components/settings/settings.js @@ -6,23 +6,35 @@ import { filter, trim } from 'lodash' const settings = { data () { + const user = this.$store.state.config + const instance = this.$store.state.instance + return { - hideAttachmentsLocal: this.$store.state.config.hideAttachments, - hideAttachmentsInConvLocal: this.$store.state.config.hideAttachmentsInConv, - hideNsfwLocal: this.$store.state.config.hideNsfw, - hidePostStatsLocal: this.$store.state.config.hidePostStats, - hideUserStatsLocal: this.$store.state.config.hideUserStats, - notificationVisibilityLocal: this.$store.state.config.notificationVisibility, - replyVisibilityLocal: this.$store.state.config.replyVisibility, - loopVideoLocal: this.$store.state.config.loopVideo, - loopVideoSilentOnlyLocal: this.$store.state.config.loopVideoSilentOnly, - muteWordsString: this.$store.state.config.muteWords.join('\n'), - autoLoadLocal: this.$store.state.config.autoLoad, - streamingLocal: this.$store.state.config.streaming, - pauseOnUnfocusedLocal: this.$store.state.config.pauseOnUnfocused, - hoverPreviewLocal: this.$store.state.config.hoverPreview, - collapseMessageWithSubjectLocal: this.$store.state.config.collapseMessageWithSubject, - stopGifs: this.$store.state.config.stopGifs, + hideAttachmentsLocal: user.hideAttachments, + hideAttachmentsInConvLocal: user.hideAttachmentsInConv, + hideNsfwLocal: user.hideNsfw, + hidePostStatsLocal: typeof user.hidePostStats === 'undefined' + ? instance.hidePostStats + : user.hidePostStats, + hidePostStatsDefault : this.$t('settings.values.' + instance.hidePostStats), + hideUserStatsLocal: typeof user.hideUserStats === 'undefined' + ? instance.hideUserStats + : user.hideUserStats, + hideUserStatsDefault : this.$t('settings.values.' + instance.hideUserStats), + notificationVisibilityLocal: user.notificationVisibility, + replyVisibilityLocal: user.replyVisibility, + loopVideoLocal: user.loopVideo, + loopVideoSilentOnlyLocal: user.loopVideoSilentOnly, + muteWordsString: user.muteWords.join('\n'), + autoLoadLocal: user.autoLoad, + streamingLocal: user.streaming, + pauseOnUnfocusedLocal: user.pauseOnUnfocused, + hoverPreviewLocal: user.hoverPreview, + collapseMessageWithSubjectLocal: typeof user.collapseMessageWithSubject === 'undefined' + ? instance.collapseMessageWithSubject + : user.collapseMessageWithSubject, + collapseMessageWithSubjectDefault: this.$t('settings.values.' + instance.collapseMessageWithSubject), + stopGifs: user.stopGifs, loopSilentAvailable: // Firefox Object.getOwnPropertyDescriptor(HTMLVideoElement.prototype, 'mozHasAudio') || @@ -40,6 +52,9 @@ const settings = { computed: { user () { return this.$store.state.users.currentUser + }, + currentSaveStateNotice () { + return this.$store.state.interface.settings.currentSaveStateNotice } }, watch: { diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue index 18e8e244..652bdcc1 100644 --- a/src/components/settings/settings.vue +++ b/src/components/settings/settings.vue @@ -1,7 +1,21 @@