diff options
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | index.html | 2 | ||||
| -rw-r--r-- | src/App.scss | 39 | ||||
| -rw-r--r-- | src/App.vue | 12 | ||||
| -rw-r--r-- | src/components/attachment/attachment.vue | 4 | ||||
| -rw-r--r-- | src/components/conversation/conversation.js | 8 | ||||
| -rw-r--r-- | src/components/conversation/conversation.vue | 2 | ||||
| -rw-r--r-- | src/components/notifications/notifications.scss | 2 | ||||
| -rw-r--r-- | src/components/notifications/notifications.vue | 4 | ||||
| -rw-r--r-- | src/components/post_status_form/post_status_form.vue | 18 | ||||
| -rw-r--r-- | src/components/status/status.js | 31 | ||||
| -rw-r--r-- | src/components/status/status.vue | 12 | ||||
| -rw-r--r-- | src/components/user_card_content/user_card_content.vue | 6 | ||||
| -rw-r--r-- | static/config.json | 2 | ||||
| -rw-r--r-- | static/css/base16-pleroma-dark.css | 33 | ||||
| -rw-r--r-- | static/css/base16-pleroma-light.css | 33 | ||||
| -rw-r--r-- | static/css/themes.json | 2 |
17 files changed, 178 insertions, 34 deletions
@@ -2,7 +2,7 @@ > A Qvitter-style frontend for certain GS servers. - + # FOR ADMINS @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> diff --git a/src/App.scss b/src/App.scss index 8a1942c6..0a7e1ce5 100644 --- a/src/App.scss +++ b/src/App.scss @@ -213,13 +213,20 @@ nav { } .main { - flex: 1; - flex-basis: 65%; + flex-basis: 60%; + flex-grow: 1; + flex-shrink: 1; } .sidebar { - flex: 1; - flex-basis: 35%; + flex: 0; + flex-basis: 35%; +} + +.sidebar-flexer { + flex: 1; + flex-basis: 345px; + width: 365px; } .mobile-shown { @@ -238,6 +245,30 @@ nav { } } +@media all and (min-width: 960px) { + .sidebar { + overflow: hidden; + max-height: 100vh; + width: 350px; + position: fixed; + margin-top: -10px; + + .sidebar-container { + height: 96vh; + width: 362px; + padding-top: 10px; + padding-right: 20px; + overflow-x: hidden; + overflow-y: scroll; + } + } + .sidebar-flexer { + max-height: 96vh; + flex-shrink: 0; + flex-grow: 0; + } +} + @media all and (max-width: 959px) { .mobile-hidden { display: none; diff --git a/src/App.vue b/src/App.vue index c4b3cb13..fcfdae97 100644 --- a/src/App.vue +++ b/src/App.vue @@ -15,10 +15,14 @@ <button @click="activatePanel('sidebar')">Sidebar</button> <button @click="activatePanel('timeline')">Timeline</button> </div> - <div class="sidebar" :class="{ 'mobile-hidden': mobileActivePanel != 'sidebar' }"> - <user-panel></user-panel> - <nav-panel></nav-panel> - <notifications v-if="currentUser"></notifications> + <div class="sidebar-flexer" :class="{ 'mobile-hidden': mobileActivePanel != 'sidebar'}"> + <div class="sidebar" :class="{ 'mobile-hidden': mobileActivePanel != 'sidebar' }"> + <div class="sidebar-container"> + <user-panel></user-panel> + <nav-panel></nav-panel> + <notifications v-if="currentUser"></notifications> + </div> + </div> </div> <div class="main" :class="{ 'mobile-hidden': mobileActivePanel != 'timeline' }"> <transition name="fade"> diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue index 1ba1c02a..d50664b6 100644 --- a/src/components/attachment/attachment.vue +++ b/src/components/attachment/attachment.vue @@ -33,10 +33,10 @@ .attachments { display: flex; flex-wrap: wrap; - margin-right: -0.8em; + margin-right: -0.7em; .attachment { flex: 1 0 30%; - margin: 0.5em 0.8em 0.6em 0.0em; + margin: 0.5em 0.7em 0.6em 0.0em; align-self: flex-start; &.html { diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index 281b0183..e89fa84f 100644 --- a/src/components/conversation/conversation.js +++ b/src/components/conversation/conversation.js @@ -8,6 +8,11 @@ const sortAndFilterConversation = (conversation) => { } const conversation = { + data () { + return { + highlight: null + } + }, props: [ 'statusoid', 'collapsable' @@ -54,6 +59,9 @@ const conversation = { } else { return (id === this.statusoid.id) } + }, + setHighlight (id) { + this.highlight = Number(id) } } } diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue index 726cfb65..8b1e00ac 100644 --- a/src/components/conversation/conversation.vue +++ b/src/components/conversation/conversation.vue @@ -8,7 +8,7 @@ </div> <div class="panel-body"> <div class="timeline"> - <status v-for="status in conversation" :key="status.id" :statusoid="status" :expandable='false' :focused="focused(status.id)" :inConversation='true'></status> + <status v-for="status in conversation" @goto="setHighlight" :key="status.id" :statusoid="status" :expandable='false' :focused="focused(status.id)" :inConversation='true' :highlight="highlight"></status> </div> </div> </div> diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss index 9bc2a5ec..c7c650a9 100644 --- a/src/components/notifications/notifications.scss +++ b/src/components/notifications/notifications.scss @@ -1,6 +1,8 @@ @import '../../_variables.scss'; .notifications { + // a bit of a hack to allow scrolling below notifications + padding-bottom: 15em; .panel-heading { // force the text to stay centered, while keeping diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue index 661d842c..a326e9cd 100644 --- a/src/components/notifications/notifications.vue +++ b/src/components/notifications/notifications.vue @@ -14,11 +14,11 @@ <div class='text'> <timeago :since="notification.action.created_at" :auto-update="240"></timeago> <div v-if="notification.type === 'favorite'"> - <h1>{{ notification.action.user.name }}<br><i class="fa icon-star"></i> favorited your <router-link :to="{ name: 'conversation', params: { id: notification.status.id } }">status</h1> + <h1>{{ notification.action.user.name }}<br><i class="fa icon-star"></i> favorited your <router-link :to="{ name: 'conversation', params: { id: notification.status.id } }">status</router-link></h1> <p>{{ notification.status.text }}</p> </div> <div v-if="notification.type === 'repeat'"> - <h1>{{ notification.action.user.name }}<br><i class="fa icon-retweet"></i> repeated your <router-link :to="{ name: 'conversation', params: { id: notification.status.id } }">status</h1> + <h1>{{ notification.action.user.name }}<br><i class="fa icon-retweet"></i> repeated your <router-link :to="{ name: 'conversation', params: { id: notification.status.id } }">status</router-link></h1> <p>{{ notification.status.text }}</p> </div> <div v-if="notification.type === 'mention'"> diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 07280a41..c3f1b1f0 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -4,6 +4,10 @@ <div class="form-group" > <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='form-bottom'> + <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> <div class="attachments"> <div class="attachment" v-for="file in newStatus.files"> <i class="fa icon-cancel" @click="removeMediaFile(file)"></i> @@ -13,10 +17,6 @@ <a v-if="type(file) === 'unknown'" :href="file.image">{{file.url}}</a> </div> </div> - <div class='form-bottom'> - <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> </template> @@ -44,14 +44,20 @@ .form-bottom { display: flex; padding: 0.5em; + height: 32px; button { - flex: 2; + width: 10em; } } .attachments { - padding: 0.5em; + padding: 0 0.5em; + + .attachment { + position: relative; + margin: 0.5em 0.8em 0.2em 0; + } i { position: absolute; diff --git a/src/components/status/status.js b/src/components/status/status.js index bb026fe1..5e7bde53 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -11,7 +11,8 @@ const Status = { 'statusoid', 'expandable', 'inConversation', - 'focused' + 'focused', + 'highlight' ], data: () => ({ replying: false, @@ -53,6 +54,16 @@ const Status = { return { borderBottomColor: this.$store.state.config.colors['base02'] } + }, + isFocused () { + // retweet or root of an expanded conversation + if (this.focused) { + return true + } else if (!this.inConversation) { + return false + } + // use conversation highlight only when in conversation + return this.status.id === this.highlight } }, components: { @@ -75,6 +86,10 @@ const Status = { toggleReplying () { this.replying = !this.replying }, + gotoOriginal () { + // only handled by conversation, not status_or_conversation + this.$emit('goto', this.status.in_reply_to_status_id) + }, toggleExpanded () { this.$emit('toggleExpanded') }, @@ -84,6 +99,20 @@ const Status = { toggleUserExpanded () { this.userExpanded = !this.userExpanded } + }, + watch: { + 'highlight': function (id) { + id = Number(id) + if (this.status.id === id) { + let rect = this.$el.getBoundingClientRect() + if (rect.top < 100) { + window.scrollBy(0, rect.top - 200) + } else if (rect.bottom > window.innerHeight - 100) { + // will be useful when scrolling down to replies or root posts is in + window.scrollBy(0, rect.bottom + 200) + } + } + } } } diff --git a/src/components/status/status.vue b/src/components/status/status.vue index b471888a..db33a200 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -1,5 +1,5 @@ <template> - <div class="status-el base00-background base03-border" v-if="!status.deleted" v-bind:class="[{ 'base01-background': focused }, { 'status-conversation': inConversation }]" > + <div class="status-el base00-background base03-border" v-if="!status.deleted" v-bind:class="[{ 'base01-background': isFocused }, { 'status-conversation': inConversation }]" > <template v-if="muted"> <div class="media status container muted"> <small><router-link :to="{ name: 'user-profile', params: { id: status.user.id } }">{{status.user.screen_name}}</router-link></small> @@ -35,12 +35,10 @@ {{status.in_reply_to_screen_name}} </router-link> </small> - <template v-if="isReply"> - <small> - <router-link :to="{ name: 'conversation', params: { id: status.in_reply_to_status_id } }"> - <i class="icon-reply"></i> - </router-link> - </small> + <template v-if="isReply && !expandable"> + <small> + <a href="#" @click.prevent="gotoOriginal" ><i class="icon-reply"></i></a> + </small> </template> - <small> diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue index 8c971d53..bba16584 100644 --- a/src/components/user_card_content/user_card_content.vue +++ b/src/components/user_card_content/user_card_content.vue @@ -79,9 +79,8 @@ return this.$store.state.users.currentUser }, dailyAvg () { - return Math.round( - this.user.statuses_count / ((new Date() - new Date(this.user.created_at)) / (60 * 60 * 24 * 1000)) - ) + const days = Math.ceil((new Date() - new Date(this.user.created_at)) / (60 * 60 * 24 * 1000)) + return Math.round(this.user.statuses_count / days) } }, methods: { @@ -117,7 +116,6 @@ } .profile-panel-body { - padding-top: 0em; top: -0em; padding-top: 4em; } diff --git a/static/config.json b/static/config.json index fb8d4015..3b6d56c4 100644 --- a/static/config.json +++ b/static/config.json @@ -1,6 +1,6 @@ { "name": "Pleroma FE", - "theme": "base16-ashes.css", + "theme": "base16-pleroma-dark.css", "background": "/static/bg.jpg", "logo": "/static/logo.png" } diff --git a/static/css/base16-pleroma-dark.css b/static/css/base16-pleroma-dark.css new file mode 100644 index 00000000..8190d2a7 --- /dev/null +++ b/static/css/base16-pleroma-dark.css @@ -0,0 +1,33 @@ +.base00-background { background-color: #161c20; } +.base01-background { background-color: #282e32; } +.base02-background { background-color: #343a3f; } +.base03-background { background-color: #4e5256; } +.base04-background { background-color: #ababab; } +.base05-background { background-color: #b9b9b9; } +.base06-background { background-color: #d0d0d0; } +.base07-background { background-color: #e7e7e7; } +.base08-background { background-color: #baaa9c; } +.base09-background { background-color: #999999; } +.base0A-background { background-color: #a0a0a0; } +.base0B-background { background-color: #8e8e8e; } +.base0C-background { background-color: #868686; } +.base0D-background { background-color: #686868; } +.base0E-background { background-color: #747474; } +.base0F-background { background-color: #5e5e5e; } + +.base00 { color: #161c20; } +.base01 { color: #282e32; } +.base02 { color: #36393e; } +.base03 { color: #4e5256; } +.base04 { color: #ababab; } +.base05 { color: #b9b9b9; } +.base06 { color: #d0d0d0; } +.base07 { color: #e7e7e7; } +.base08 { color: #baaa9c; } +.base09 { color: #999999; } +.base0A { color: #a0a0a0; } +.base0B { color: #8e8e8e; } +.base0C { color: #868686; } +.base0D { color: #686868; } +.base0E { color: #747474; } +.base0F { color: #5e5e5e; } diff --git a/static/css/base16-pleroma-light.css b/static/css/base16-pleroma-light.css new file mode 100644 index 00000000..1a85689a --- /dev/null +++ b/static/css/base16-pleroma-light.css @@ -0,0 +1,33 @@ +.base00-background { background-color: #f2f4f6; } +.base01-background { background-color: #dde2e6; } +.base02-background { background-color: #c0c6cb; } +.base03-background { background-color: #a4a4a4; } +.base04-background { background-color: #545454; } +.base05-background { background-color: #304055; } +.base06-background { background-color: #040404; } +.base07-background { background-color: #000000; } +.base08-background { background-color: #e92f2f; } +.base09-background { background-color: #e09448; } +.base0A-background { background-color: #dddd13; } +.base0B-background { background-color: #0ed839; } +.base0C-background { background-color: #23edda; } +.base0D-background { background-color: #3b48e3; } +.base0E-background { background-color: #f996e2; } +.base0F-background { background-color: #69542d; } + +.base00 { color: #f2f4f6; } +.base01 { color: #dde2e6; } +.base02 { color: #c0c6cb; } +.base03 { color: #a4a4a4; } +.base04 { color: #545454; } +.base05 { color: #304055; } +.base06 { color: #040404; } +.base07 { color: #000000; } +.base08 { color: #e46f0f; } +.base09 { color: #e09448; } +.base0A { color: #dddd13; } +.base0B { color: #0ed839; } +.base0C { color: #23edda; } +.base0D { color: #3b48e3; } +.base0E { color: #f996e2; } +.base0F { color: #69542d; } diff --git a/static/css/themes.json b/static/css/themes.json index e3c35d6d..ea8e5a0c 100644 --- a/static/css/themes.json +++ b/static/css/themes.json @@ -1,4 +1,6 @@ [ +"base16-pleroma-dark.css", +"base16-pleroma-light.css", "base16-3024.css", "base16-apathy.css", "base16-ashes.css", |
