diff options
Diffstat (limited to 'src')
21 files changed, 383 insertions, 190 deletions
diff --git a/src/App.scss b/src/App.scss index 431aeb32..0945c76b 100644 --- a/src/App.scss +++ b/src/App.scss @@ -32,9 +32,10 @@ a { button{ border: none; border-radius: 5px; + cursor: pointer; &:hover { - background-color: white; + opacity: 0.8; } } @@ -102,11 +103,11 @@ main-router { flex-direction: column; margin: 0.5em; - border-radius: 0.5em; + border-radius: 10px; } .panel-heading { - border-radius: 0.5em 0.5em 0 0; + border-radius: 10px 10px 0 0; background-size: cover; padding: 0.6em 0; text-align: center; @@ -115,7 +116,7 @@ main-router { } .panel-footer { - border-radius: 0 0 0.5em 0.5em; + border-radius: 0 0 10px 10px; } .panel-body > p { @@ -128,7 +129,7 @@ main-router { #content { margin: auto; max-width: 980px; - border-radius: 1em; + border-radius: 10px; padding-bottom: 1em; background-color: rgba(0,0,0,0.1); } @@ -142,46 +143,10 @@ main-router { min-width: 0px; } -.user-info { - color: white; - padding: 1em; - img { - border: 2px solid; - border-radius: 0.5em - } - text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5); - .user-name{ - margin-top: 0.2em; - } - .user-screen-name { - margin-top: 0.3em; - font-weight: lighter; - padding-right: 0.1em; - } -} - -.user-counts { - display: flex; - line-height:16px; - padding: 1em 1.5em 0em 1em; - text-align: center; -} - -.user-count { - flex: 1; - - h5 { - font-size:1em; - font-weight: bolder; - margin: 0 0 0.25em; - } -} - .fa { color: grey; } - .status-actions { width: 50%; display: flex; @@ -210,7 +175,7 @@ status-text-container { margin-top: 0.2em; float: right; margin-right: 0.3em; - border-radius: 20%; + border-radius: 5px; } } diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js index 57d21b28..f4f6aebf 100644 --- a/src/components/attachment/attachment.js +++ b/src/components/attachment/attachment.js @@ -7,16 +7,19 @@ const Attachment = { 'nsfw', 'statusId' ], - data: () => ({ - nsfwImage, - showHidden: false - }), + data () { + return { + nsfwImage, + hideNsfwLocal: this.$store.state.config.hideNsfw, + showHidden: false + } + }, computed: { type () { return fileTypeService.fileType(this.attachment.mimetype) }, hidden () { - return this.nsfw && !this.showHidden + return this.nsfw && this.hideNsfwLocal && !this.showHidden } }, methods: { diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue index 738a1e86..ad60acf9 100644 --- a/src/components/attachment/attachment.vue +++ b/src/components/attachment/attachment.vue @@ -3,7 +3,7 @@ <a class="image-attachment" v-if="hidden" v-on:click.prevent="toggleHidden()"> <img :key="nsfwImage" :src="nsfwImage"></img> </a> - <div class="hider" v-if="nsfw && !hidden"> + <div class="hider" v-if="nsfw && hideNsfwLocal && !hidden"> <a href="#" @click.prevent="toggleHidden()">Hide</a> </div> @@ -16,8 +16,6 @@ <audio v-if="type === 'audio'" :src="attachment.url" controls></audio> - <span v-if="type === 'unknown'">Don't know how to display this...</span> - <div @click.prevent="linkClicked" v-if="type === 'html' && attachment.oembed" class="oembed"> <div v-if="attachment.thumb_url" class="image"> <img :src="attachment.thumb_url"></img> @@ -36,14 +34,15 @@ .attachments { display: flex; flex-wrap: wrap; + margin-right: -0.8em; .attachment { flex: 1 0 30%; - display: flex; - margin: 0.5em 0.8em 0.6em 0.1em; + margin: 0.5em 0.8em 0.6em 0.0em; align-self: flex-start; &.html { flex-basis: 100%; + display: flex; } .hider { @@ -51,14 +50,14 @@ margin: 10px; padding: 5px; background: rgba(230,230,230,0.6); - border-radius: 0.5em; + border-radius: 5px; font-weight: bold; } video { height: 100%; border: 1px solid; - border-radius: 0.5em; + border-radius: 5px; width: 100%; } @@ -71,7 +70,7 @@ height: 100%; flex: 1; border: 1px solid; - border-radius: 0.5em; + border-radius: 5px; } @@ -91,7 +90,7 @@ flex: 1; img { border: 0px; - border-radius: 0; + border-radius: 5px; height: 100%; object-fit: cover; } @@ -115,7 +114,7 @@ width: 100%; border-style: solid; border-width: 1px; - border-radius: 0.5em; + border-radius: 5px; width: 100%; height: 100%; /* If this isn't here, chrome will stretch the images */ } diff --git a/src/components/delete_button/delete_button.js b/src/components/delete_button/delete_button.js index 726509d0..77da1b87 100644 --- a/src/components/delete_button/delete_button.js +++ b/src/components/delete_button/delete_button.js @@ -2,7 +2,7 @@ const DeleteButton = { props: [ 'status' ], methods: { deleteStatus () { - const confirmed = confirm('Do you really want to delete this status?') + const confirmed = window.confirm('Do you really want to delete this status?') if (confirmed) { this.$store.dispatch('deleteStatus', { id: this.status.id }) } @@ -10,7 +10,7 @@ const DeleteButton = { }, computed: { currentUser () { return this.$store.state.users.currentUser }, - canDelete () { return this.currentUser.rights.delete_others_notice || this.status.user.id == this.currentUser.id } + canDelete () { return this.currentUser.rights.delete_others_notice || this.status.user.id === this.currentUser.id } } } diff --git a/src/components/login_form/login_form.vue b/src/components/login_form/login_form.vue index c0169a08..c0ea4313 100644 --- a/src/components/login_form/login_form.vue +++ b/src/components/login_form/login_form.vue @@ -1,11 +1,11 @@ <template> <div class="login panel panel-default base00-background"> <!-- Default panel contents --> - <div class="panel-heading base01-background base04"> + <div class="panel-heading base01-background"> Log in </div> <div class="panel-body"> - <form v-on:submit.prevent='submit(user)'> + <form v-on:submit.prevent='submit(user)' class='login-form'> <div class='form-group'> <label for='username'>Username</label> <input :disabled="loggingIn" v-model='user.username' class='form-control' id='username' placeholder='e.g. lain'> @@ -15,7 +15,7 @@ <input :disabled="loggingIn" v-model='user.password' class='form-control' id='password' type='password'> </div> <div class='form-group'> - <button :disabled="loggingIn" type='submit' class='btn btn-default'>Submit</button> + <button :disabled="loggingIn" type='submit' class='btn btn-default base05 base01-background'>Submit</button> </div> </form> </div> @@ -23,3 +23,22 @@ </template> <script src="./login_form.js" ></script> + +<style lang="scss"> + +.login-form { + input { + border-width: 1px; + border-style: solid; + border-color: silver; + border-radius: 5px; + padding: 0.1em 0.2em 0.2em 0.2em; + } + + .btn { + margin-top: 1.0em; + min-height: 28px; + } +} + +</style> diff --git a/src/components/media_upload/media_upload.js b/src/components/media_upload/media_upload.js index 3f2e3964..8b4e7ad4 100644 --- a/src/components/media_upload/media_upload.js +++ b/src/components/media_upload/media_upload.js @@ -3,12 +3,22 @@ import statusPosterService from '../../services/status_poster/status_poster.serv const mediaUpload = { mounted () { - const store = this.$store const input = this.$el.querySelector('input') - const self = this input.addEventListener('change', ({target}) => { const file = target.files[0] + this.uploadFile(file) + }) + }, + data () { + return { + uploading: false + } + }, + methods: { + uploadFile (file) { + const self = this + const store = this.$store const formData = new FormData() formData.append('media', file) @@ -19,15 +29,34 @@ const mediaUpload = { .then((fileData) => { self.$emit('uploaded', fileData) self.uploading = false - }, (error) => { + }, (error) => { // eslint-disable-line handle-callback-err self.$emit('upload-failed') self.uploading = false }) - }) + }, + fileDrop (e) { + if (e.dataTransfer.files.length > 0) { + e.preventDefault() // allow dropping text like before + this.uploadFile(e.dataTransfer.files[0]) + } + }, + fileDrag (e) { + let types = e.dataTransfer.types + if (types.contains('Files')) { + e.dataTransfer.dropEffect = 'copy' + } else { + e.dataTransfer.dropEffect = 'none' + } + } }, - data () { - return { - uploading: false + props: [ + 'dropFiles' + ], + watch: { + 'dropFiles': function (fileInfos) { + if (!this.uploading) { + this.uploadFile(fileInfos[0]) + } } } } diff --git a/src/components/media_upload/media_upload.vue b/src/components/media_upload/media_upload.vue index 3302db37..b839067b 100644 --- a/src/components/media_upload/media_upload.vue +++ b/src/components/media_upload/media_upload.vue @@ -1,5 +1,5 @@ <template> - <div class="media-upload"> + <div class="media-upload" @drop.prevent @dragover.prevent="fileDrag" @drop="fileDrop"> <label class="btn btn-default"> <i class="fa icon-spin4 animate-spin" v-if="uploading"></i> <i class="fa icon-upload" v-if="!uploading"></i> diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss index 517afeaa..5da6d495 100644 --- a/src/components/notifications/notifications.scss +++ b/src/components/notifications/notifications.scss @@ -1,45 +1,65 @@ @import '../../_variables.scss'; -.notification { - padding: 0.4em 0 0 0.7em; - display: flex; - border-bottom: 1px solid silver; - - .text { - min-width: 0px; - word-wrap: break-word; - line-height:18px; - - .icon-retweet { - color: $green; - } - - .icon-reply { - color: $blue; - } - h1 { - margin: 0 0 0.3em; - padding: 0; - font-size: 1em; - line-height:20px; - } +.notifications { - padding: 0.3em 0.8em 0.5em; - p { - margin: 0; - margin-top: 0; - margin-bottom: 0.3em; + .panel-heading { + // force the text to stay centered, while keeping + // the button in the right side of the panel heading + position: relative; + button { + position: absolute; + padding: 0.1em 0.3em 0.25em 0.3em; + right: 0.6em; } } - .avatar { - padding-top: 0.3em; - width: 32px; - height: 32px; - border-radius: 50%; + .unseen { + border-left: 4px solid rgba(255, 48, 16, 0.65); } - &:last-child { - border: none + .notification { + padding: 0.4em 0 0 0.7em; + display: flex; + border-bottom: 1px solid silver; + + + .text { + min-width: 0px; + word-wrap: break-word; + line-height:18px; + + .icon-retweet { + color: $green; + } + + .icon-reply { + color: $blue; + } + + h1 { + margin: 0 0 0.3em; + padding: 0; + font-size: 1em; + line-height:20px; + } + + padding: 0.3em 0.8em 0.5em; + p { + margin: 0; + margin-top: 0; + margin-bottom: 0.3em; + } + } + + .avatar { + padding-top: 0.3em; + width: 32px; + height: 32px; + border-radius: 50%; + } + + &:last-child { + border: none + } } } diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue index 785cc019..41c274aa 100644 --- a/src/components/notifications/notifications.vue +++ b/src/components/notifications/notifications.vue @@ -1,9 +1,12 @@ <template> <div class="notifications"> <div class="panel panel-default base00-background"> - <div class="panel-heading base01-background base04">Notifications ({{unseenCount}}) <button @click.prevent="markAsSeen">Read!</button></div> + <div class="panel-heading base01-background base04"> + Notifications ({{unseenCount}}) + <button @click.prevent="markAsSeen" class="base05 base02-background">Read!</button> + </div> <div class="panel-body"> - <div v-for="notification in visibleNotifications" class="notification" :class='{"base01-background": notification.seen}'> + <div v-for="notification in visibleNotifications" class="notification" :class='{"unseen": !notification.seen}'> <a :href="notification.action.user.statusnet_profile_url"> <img class='avatar' :src="notification.action.user.profile_image_url_original"> </a> diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 3365c569..01aeeb68 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -49,7 +49,7 @@ const defaultCollection = { menuContainer: document.body, // column to search against in the object (accepts function or string) - lookup: ({name, screen_name}) => `${name} (@${screen_name})`, + lookup: ({name, screen_name}) => `${name} (@${screen_name})`, // eslint-disable-line camelcase // column that contains the content to insert by default fillAttr: 'screen_name', @@ -84,6 +84,7 @@ const PostStatusForm = { } return { + dropFiles: [], submitDisabled: false, newStatus: { status: statusText, @@ -141,6 +142,15 @@ const PostStatusForm = { }, type (fileInfo) { return fileTypeService.fileType(fileInfo.mimetype) + }, + fileDrop (e) { + if (e.dataTransfer.files.length > 0) { + e.preventDefault() // allow dropping text like before + this.dropFiles = e.dataTransfer.files + } + }, + fileDrag (e) { + e.dataTransfer.dropEffect = 'copy' } } } diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 1bad41c7..07280a41 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -2,20 +2,20 @@ <div class="post-status-form"> <form @submit.prevent="postStatus(newStatus)"> <div class="form-group" > - <textarea v-model="newStatus.status" placeholder="Just landed in L.A." rows="3" class="form-control" @keyup.ctrl.enter="postStatus(newStatus)"></textarea> + <textarea v-model="newStatus.status" placeholder="Just landed in L.A." rows="3" class="form-control" @keyup.meta.enter="postStatus(newStatus)" @keyup.ctrl.enter="postStatus(newStatus)" @drop="fileDrop" @dragover.prevent="fileDrag"></textarea> </div> <div class="attachments"> <div class="attachment" v-for="file in newStatus.files"> + <i class="fa icon-cancel" @click="removeMediaFile(file)"></i> <img class="thumbnail media-upload" :src="file.image" v-if="type(file) === 'image'"></img> <video v-if="type(file) === 'video'" :src="file.image" controls></video> <audio v-if="type(file) === 'audio'" :src="file.image" controls></audio> <a v-if="type(file) === 'unknown'" :href="file.image">{{file.url}}</a> - <i class="fa icon-cancel" @click="removeMediaFile(file)"></i> </div> </div> <div class='form-bottom'> - <media-upload @uploading="disableSubmit" @uploaded="addMediaFile" @upload-failed="enableSubmit"></media-upload> - <button :disabled="submitDisabled" type="submit" class="btn btn-default">Submit</button> + <media-upload @uploading="disableSubmit" @uploaded="addMediaFile" @upload-failed="enableSubmit" :drop-files="dropFiles"></media-upload> + <button :disabled="submitDisabled" type="submit" class="btn btn-default base05 base01-background">Submit</button> </div> </form> </div> @@ -52,6 +52,15 @@ .attachments { padding: 0.5em; + + i { + position: absolute; + margin: 10px; + padding: 5px; + background: rgba(230,230,230,0.6); + border-radius: 5px; + font-weight: bold; + } } form { @@ -68,10 +77,12 @@ } form textarea { - border: none; - border-radius: 2px; + border: solid; + border-width: 1px; + border-color: silver; + border-radius: 5px; line-height:16px; - padding: 0.5em; + padding: 5px; resize: vertical; } diff --git a/src/components/settings/settings.js b/src/components/settings/settings.js index f979e7ab..c1b88f82 100644 --- a/src/components/settings/settings.js +++ b/src/components/settings/settings.js @@ -1,8 +1,22 @@ import StyleSwitcher from '../style_switcher/style_switcher.vue' const settings = { + data () { + return { + hideAttachmentsLocal: this.$store.state.config.hideAttachments, + hideNsfwLocal: this.$store.state.config.hideNsfw + } + }, components: { StyleSwitcher + }, + watch: { + hideAttachmentsLocal (value) { + this.$store.dispatch('setOption', { name: 'hideAttachments', value }) + }, + hideNsfwLocal (value) { + this.$store.dispatch('setOption', { name: 'hideNsfw', value }) + } } } diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue index 57aafac8..89b89a39 100644 --- a/src/components/settings/settings.vue +++ b/src/components/settings/settings.vue @@ -8,6 +8,13 @@ <h2>Theme</h2> <style-switcher></style-switcher> </div> + <div class="setting-item"> + <h2>Attachments</h2> + <input type="checkbox" id="hideAttachments" v-model="hideAttachmentsLocal"> + <label for="hideAttachments">Hide Attachments</label> + <input type="checkbox" id="hideNsfw" v-model="hideNsfwLocal"> + <label for="hideNsfw">Enable clickthrough NSFW attachment hiding</label> + </div> </div> </div> </template> diff --git a/src/components/status/status.js b/src/components/status/status.js index 46add8aa..22292ffa 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -17,6 +17,7 @@ const Status = { userExpanded: false }), computed: { + hideAttachments () { return this.$store.state.config.hideAttachments }, retweet () { return !!this.statusoid.retweeted_status }, retweeter () { return this.statusoid.user.name }, status () { diff --git a/src/components/status/status.vue b/src/components/status/status.vue index f111c2d5..585bf621 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -57,7 +57,7 @@ <div @click.prevent="linkClicked" class="status-content" v-html="status.statusnet_html"></div> <div v-if='status.attachments' class='attachments'> - <attachment :status-id="status.id" :nsfw="status.nsfw" :attachment="attachment" v-for="attachment in status.attachments"> + <attachment v-if="!hideAttachments" :status-id="status.id" :nsfw="status.nsfw" :attachment="attachment" v-for="attachment in status.attachments"> </attachment> </div> </div> @@ -157,7 +157,8 @@ .usercard { border-style: solid; border-width: 1px; - border-radius: 1em; + border-radius: 10px; margin-bottom: 1em; + margin-top: 0.2em; } </style> diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue index 59cee734..178100b8 100644 --- a/src/components/user_card_content/user_card_content.vue +++ b/src/components/user_card_content/user_card_content.vue @@ -1,40 +1,42 @@ <template> - <div> - <div class="base00-background panel-heading text-center" v-bind:style="style"> + <div id="heading" class="profile-panel-background" :style="headingStyle"> + <div class="panel-heading text-center"> <div class='user-info'> - <img :src="user.profile_image_url"> - <span class="glyphicon glyphicon-user"></span> - <div class='user-name'>{{user.name}}</div> - <div class='user-screen-name'>@{{user.screen_name}}</div> + <div class='container'> + <img :src="user.profile_image_url"> + <span class="glyphicon glyphicon-user"></span> + <div class='user-name'>{{user.name}}</div> + <div class='user-screen-name'>@{{user.screen_name}}</div> + </div> <div v-if="isOtherUser" class="user-interactions"> - <div v-if="user.follows_you" class="following base06"> + <div v-if="user.follows_you && loggedIn" class="following base06"> Follows you! </div> - <div class="follow"> + <div class="follow" v-if="loggedIn"> <span v-if="user.following"> <!--Following them!--> - <button @click="unfollowUser" class="base06 base01-background base06-border"> - Unfollow + <button @click="unfollowUser" class="base04 base00-background pressed"> + Following! </button> </span> <span v-if="!user.following"> - <button @click="followUser" class="base01 base04-background base01-border"> + <button @click="followUser" class="base05 base02-background"> Follow </button> </span> </div> <div class='mute' v-if='isOtherUser'> <span v-if='user.muted'> - <button @click="toggleMute" class="base04 base01-background base06-border">Unmute</button> + <button @click="toggleMute" class="base04 base00-background pressed">Muted</button> </span> <span v-if='!user.muted'> - <button @click="toggleMute" class="base01 base04-background base01-border">Mute</button> + <button @click="toggleMute" class="base05 base02-background">Mute</button> </span> </div> </div> </div> </div> - <div class="panel-body base00-background"> + <div class="panel-body profile-panel-body" :style="bodyStyle"> <div class="user-counts"> <div class="user-count"> <h5>Statuses</h5> @@ -58,14 +60,25 @@ export default { props: [ 'user' ], computed: { - style () { + headingStyle () { + let rgb = this.$store.state.config.colors['base00'].match(/\d+/g) return { - color: `#${this.user.profile_link_color}`, - 'background-image': `url(${this.user.cover_photo})` + backgroundColor: 'rgb(' + Math.floor(rgb[0] * 0.53) + ', ' + + Math.floor(rgb[1] * 0.56) + ', ' + + Math.floor(rgb[2] * 0.59) + ')', + backgroundImage: `url(${this.user.cover_photo})` + } + }, + bodyStyle () { + return { + background: 'linear-gradient(to bottom, rgba(0, 0, 0, 0), ' + this.$store.state.config.colors['base00'] + ' 80%)' } }, isOtherUser () { return this.user !== this.$store.state.users.currentUser + }, + loggedIn () { + return this.$store.state.users.currentUser } }, methods: { @@ -87,3 +100,118 @@ } } </script> + +<style lang="scss"> + +.profile-panel-background { + background-size: cover; + border-radius: 10px; +} + +.profile-panel-body { + padding-top: 0em; + top: -0em; + padding-top: 4em; +} + +.user-info { + color: white; + padding: 16px 16px 16px 16px; + margin-bottom: -4em; + + .container{ + display: flex; + flex-wrap: wrap; + flex-direction: column; + align-content: flex-start; + justify-content: center; + max-height: 60px; + } + + img { + border: 2px solid; + border-radius: 5px; + flex: 1 0 100%; + max-width: 48px; + max-height: 48px; + } + + text-shadow: 0px 1px 1.5px rgba(0, 0, 0, 1.0); + + .user-name{ + margin-top: 0.0em; + margin-left: 0.6em; + flex: 0 0 auto; + align-self: flex-start; + } + + .user-screen-name { + margin-top: 0.0em; + margin-left: 0.6em; + font-weight: lighter; + font-size: 15px; + padding-right: 0.1em; + flex: 0 0 auto; + align-self: flex-start; + } + + .user-interactions { + display: flex; + flex-flow: row wrap; + justify-content: space-between; + + div { + flex: 1; + } + margin-top: 0.7em; + margin-bottom: -1.0em; + + .following { + color: white; + font-size: 14px; + flex: 0 0 100%; + margin: -0.7em 0.0em 0.3em 0.0em; + padding-left: 16px; + text-align: left; + } + + .mute { + max-width: 220px; + min-height: 28px; + } + + .follow { + max-width: 220px; + min-height: 28px; + } + + button { + border: solid; + border-width: 1px; + width: 92%; + height: 100%; + } + .pressed { + border: solid; + border-width: 1px; + } + } +} + +.user-counts { + display: flex; + line-height:16px; + padding: 1em 1.5em 0em 1em; + text-align: center; +} + +.user-count { + flex: 1; + + h5 { + font-size:1em; + font-weight: bolder; + margin: 0 0 0.25em; + } +} +</style> diff --git a/src/components/user_profile/user_profile.vue b/src/components/user_profile/user_profile.vue index b0d6db85..11a61bfc 100644 --- a/src/components/user_profile/user_profile.vue +++ b/src/components/user_profile/user_profile.vue @@ -7,45 +7,10 @@ <script src="./user_profile.js"></script> <style lang="scss"> - .user-profile { - flex: 2; - flex-basis: 500px; - } - .user-info { - .user-interactions { - display: flex; - flex-flow: row wrap; - justify-content: center; +.user-profile { + flex: 2; + flex-basis: 500px; +} - div { - flex: 1; - } - margin-top: 0.5em; - margin-bottom: -1.2em; - - .following { - font-size: 14px; - flex: 0 0 100%; - margin-bottom: 0.5em; - } - - .mute { - max-width: 200px; - } - - .follow { - max-width: 200px; - } - - button { - width: 80%; - height: 100%; - border: 1px solid; - } - } - .user-screen-name { - margin-top: 0.4em; - } - } </style> diff --git a/src/lib/persisted_state.js b/src/lib/persisted_state.js index de1e5383..6a17ca99 100644 --- a/src/lib/persisted_state.js +++ b/src/lib/persisted_state.js @@ -1,7 +1,7 @@ import merge from 'lodash.merge' import objectPath from 'object-path' import { throttle } from 'lodash' -import { inflate, deflate } from 'pako' +import lzstring from 'lz-string' const defaultReducer = (state, paths) => ( paths.length === 0 ? state : paths.reduce((substate, path) => { @@ -36,22 +36,22 @@ const defaultStorage = (() => { })() const defaultSetState = (key, state, storage) => { - return storage.setItem(key, deflate(JSON.stringify(state), { to: 'string' })) + return storage.setItem(key, lzstring.compressToUTF16(JSON.stringify(state))) } export default function createPersistedState ({ - key = 'vuex', + key = 'vuex-lz', paths = [], getState = (key, storage) => { let value = storage.getItem(key) try { - value = inflate(value, { to: 'string' }) + value = lzstring.decompressFromUTF16(value) // inflate(value, { to: 'string' }) } catch (e) { console.log("Couldn't inflate value... Maybe upgrading") } return value && value !== 'undefined' ? JSON.parse(value) : undefined }, - setState = throttle(defaultSetState, 5000), + setState = throttle(defaultSetState, 60000), reducer = defaultReducer, storage = defaultStorage, subscriber = store => handler => store.subscribe(handler) diff --git a/src/main.js b/src/main.js index 6fa95e12..0783749e 100644 --- a/src/main.js +++ b/src/main.js @@ -29,7 +29,12 @@ Vue.use(VueTimeago, { }) const persistedStateOptions = { - paths: ['users.users', 'statuses.notifications'] + paths: [ + 'config.hideAttachments', + 'config.hideNsfw', + 'statuses.notifications', + 'users.users' + ] } const store = new Vuex.Store({ diff --git a/src/modules/config.js b/src/modules/config.js index a1276519..896a6978 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -2,7 +2,10 @@ import { set } from 'vue' import StyleSetter from '../services/style_setter/style_setter.js' const defaultState = { - name: 'Pleroma FE' + name: 'Pleroma FE', + colors: {}, + hideAttachments: false, + hideNsfw: true } const config = { @@ -24,7 +27,7 @@ const config = { break case 'theme': const fullPath = `/static/css/${value}` - StyleSetter.setStyle(fullPath) + StyleSetter.setStyle(fullPath, commit) } } } diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js index 0a5be77d..7129852d 100644 --- a/src/services/style_setter/style_setter.js +++ b/src/services/style_setter/style_setter.js @@ -1,4 +1,6 @@ -const setStyle = (href) => { +import { times } from 'lodash' + +const setStyle = (href, commit) => { /*** What's going on here? I want to make it easy for admins to style this application. To have @@ -23,18 +25,26 @@ const setStyle = (href) => { const setDynamic = () => { const baseEl = document.createElement('div') body.appendChild(baseEl) - baseEl.setAttribute('class', 'base05') - const base05Color = window.getComputedStyle(baseEl).getPropertyValue('color') - baseEl.setAttribute('class', 'base08') - const base08Color = window.getComputedStyle(baseEl).getPropertyValue('color') + + let colors = {} + times(16, (n) => { + const name = `base0${n.toString(16).toUpperCase()}` + baseEl.setAttribute('class', name) + const color = window.getComputedStyle(baseEl).getPropertyValue('color') + colors[name] = color + }) + + commit('setOption', { name: 'colors', value: colors }) + + body.removeChild(baseEl) + const styleEl = document.createElement('style') head.appendChild(styleEl) const styleSheet = styleEl.sheet - body.removeChild(baseEl) - styleSheet.insertRule(`a { color: ${base08Color}`, 'index-max') - styleSheet.insertRule(`body { color: ${base05Color}`, 'index-max') - styleSheet.insertRule(`.base05-border { border-color: ${base05Color}`, 'index-max') + styleSheet.insertRule(`a { color: ${colors['base08']}`, 'index-max') + styleSheet.insertRule(`body { color: ${colors['base05']}`, 'index-max') + styleSheet.insertRule(`.base05-border { border-color: ${colors['base05']}`, 'index-max') body.style.display = 'initial' } cssEl.addEventListener('load', setDynamic) |
