Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85630096
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
25 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/components/delete_button/delete_button.vue b/src/components/delete_button/delete_button.vue
index 304f8a6336..845ac777ea 100644
--- a/src/components/delete_button/delete_button.vue
+++ b/src/components/delete_button/delete_button.vue
@@ -1,20 +1,20 @@
<template>
<div v-if="canDelete">
<a href="#" v-on:click.prevent="deleteStatus()">
- <i class='fa icon-cancel delete-status'></i>
+ <i class='base09 icon-cancel delete-status'></i>
</a>
</div>
</template>
<script src="./delete_button.js" ></script>
<style lang='scss'>
@import '../../_variables.scss';
.icon-cancel,.delete-status {
cursor: pointer;
&:hover {
color: $red;
}
}
</style>
diff --git a/src/components/favorite_button/favorite_button.vue b/src/components/favorite_button/favorite_button.vue
index 0abece31e2..044e67965a 100644
--- a/src/components/favorite_button/favorite_button.vue
+++ b/src/components/favorite_button/favorite_button.vue
@@ -1,22 +1,22 @@
<template>
<div>
- <i :class='classes' class='favorite-button fa' @click.prevent='favorite()'/>
+ <i :class='classes' class='favorite-button base09' @click.prevent='favorite()'/>
<span v-if='status.fave_num > 0'>{{status.fave_num}}</span>
</div>
</template>
<script src="./favorite_button.js" ></script>
<style lang='scss'>
.favorite-button {
cursor: pointer;
animation-duration: 0.6s;
&:hover {
color: orange;
}
}
.icon-star {
color: orange;
}
</style>
diff --git a/src/components/media_upload/media_upload.vue b/src/components/media_upload/media_upload.vue
index b839067bc9..9e6ad60891 100644
--- a/src/components/media_upload/media_upload.vue
+++ b/src/components/media_upload/media_upload.vue
@@ -1,22 +1,22 @@
<template>
<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>
+ <i class="base09 icon-spin4 animate-spin" v-if="uploading"></i>
+ <i class="base09 icon-upload" v-if="!uploading"></i>
<input type=file style="position: fixed; top: -100em"></input>
</label>
</div>
</template>
<script src="./media_upload.js" ></script>
<style>
.media-upload {
font-size: 26px;
flex: 1;
}
.icon-upload {
cursor: pointer;
}
</style>
diff --git a/src/components/retweet_button/retweet_button.vue b/src/components/retweet_button/retweet_button.vue
index d923c5c482..3226d5c6fd 100644
--- a/src/components/retweet_button/retweet_button.vue
+++ b/src/components/retweet_button/retweet_button.vue
@@ -1,22 +1,22 @@
<template>
<div>
- <i :class='classes' class='icon-retweet fa' v-on:click.prevent='retweet()'></i>
+ <i :class='classes' class='icon-retweet base09' v-on:click.prevent='retweet()'></i>
<span v-if='status.repeat_num > 0'>{{status.repeat_num}}</span>
</div>
</template>
<script src="./retweet_button.js" ></script>
<style lang='scss'>
@import '../../_variables.scss';
.icon-retweet {
cursor: pointer;
animation-duration: 0.6s;
&:hover {
color: $green;
}
}
.retweeted {
color: $green;
}
</style>
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 5e3df8babb..55c89e6c0f 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -1,426 +1,426 @@
<template>
<div class="status-el base00-background" v-if="compact">
<div @click.prevent="linkClicked" class="status-content" v-html="status.statusnet_html"></div>
<div v-if="loggedIn">
<div class='status-actions'>
<div>
<a href="#" v-on:click.prevent="toggleReplying">
- <i class="fa icon-reply" :class="{'icon-reply-active': replying}"></i>
+ <i class="base09 icon-reply" :class="{'icon-reply-active': replying}"></i>
</a>
</div>
<retweet-button :status=status></retweet-button>
<favorite-button :status=status></favorite-button>
</div>
</div>
<post-status-form class="reply-body" :reply-to="status.id" :attentions="status.attentions" :repliedUser="status.user" v-on:posted="toggleReplying" v-if="replying"/>
</div>
<div class="status-el base00-background base03-border status-fadein" v-else-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>
<small class="muteWords">{{muteWordHits.join(', ')}}</small>
- <a href="#" class="unmute" @click.prevent="toggleMute"><i class="fa icon-eye-off"></i></a>
+ <a href="#" class="unmute" @click.prevent="toggleMute"><i class="base09 icon-eye-off"></i></a>
</div>
</template>
<template v-if="!muted">
<div v-if="retweet" class="media container retweet-info">
<div class="media-left">
<i class='fa icon-retweet retweeted'></i>
</div>
<div class="media-body">
Repeated by <a :href="statusoid.user.statusnet_profile_url" style="font-weight: bold;" :title="'@'+statusoid.user.screen_name">{{retweeter}}</a>
</div>
</div>
<div class="media status container">
<div class="media-left">
<a :href="status.user.statusnet_profile_url">
<img @click.prevent="toggleUserExpanded" :class="{retweeted: retweet}" class='avatar' :src="status.user.profile_image_url_original">
<img v-if="retweet" class='avatar-retweeter' :src="statusoid.user.profile_image_url_original"></img>
</a>
</div>
<div class="media-body">
<div class="base03-border usercard" v-if="userExpanded">
<user-card-content :user="status.user" :switcher="false"></user-card-content>
</div>
<div class="user-content">
<div class="media-heading">
<div class="name-and-links">
<h4 class="user-name">{{status.user.name}}</h4>
<div class="links">
<h4>
<small><router-link :to="{ name: 'user-profile', params: { id: status.user.id } }">{{status.user.screen_name}}</router-link></small>
<small v-if="status.in_reply_to_screen_name"> >
<router-link :to="{ name: 'user-profile', params: { id: status.in_reply_to_user_id } }">
{{status.in_reply_to_screen_name}}
</router-link>
</small>
<template v-if="isReply">
<small>
<a href="#" @click.prevent="gotoOriginal(status.in_reply_to_status_id)"><i class="icon-reply" @mouseenter="replyEnter(status.in_reply_to_status_id, $event)" @mouseout="replyLeave()"></i></a>
</small>
</template>
-
<small>
<router-link :to="{ name: 'conversation', params: { id: status.id } }">
<timeago :since="status.created_at" :auto-update="60"></timeago>
</router-link>
</small>
</h4>
</div>
<h4 class="replies" v-if="inConversation">
<small v-if="replies.length">Replies:</small>
<small v-for="reply in replies">
<a href="#" @click.prevent="gotoOriginal(reply.id)" @mouseenter="replyEnter(reply.id, $event)" @mouseout="replyLeave()">{{reply.name}} </a>
</small>
</h4>
</div>
<div class="heading-icons">
- <a href="#" @click.prevent="toggleMute" v-if="unmuted"><i class="fa icon-eye-off"></i></a>
- <a :href="status.external_url" target="_blank" v-if="!status.is_local" class="source_url"><i class="fa icon-binoculars"></i></a>
+ <a href="#" @click.prevent="toggleMute" v-if="unmuted"><i class="base09 icon-eye-off"></i></a>
+ <a :href="status.external_url" target="_blank" v-if="!status.is_local" class="source_url"><i class="base09 icon-binoculars"></i></a>
<template v-if="expandable">
- <a href="#" @click.prevent="toggleExpanded" class="expand"><i class="fa icon-plus-squared"></i></a>
+ <a href="#" @click.prevent="toggleExpanded" class="expand"><i class="base09 icon-plus-squared"></i></a>
</template>
</div>
</div>
<div class="status-preview base00-background base03-border" v-if="showPreview && preview">
<img class="avatar" :src="preview.user.profile_image_url_original">
<div class="text">
<h4>
{{ preview.user.name }}
<small><a>{{ preview.user.screen_name}}</a></small>
</h4>
<div @click.prevent="linkClicked" class="status-content" v-html="preview.statusnet_html"></div>
</div>
</div>
<div class="status-preview status-preview-loading base00-background base03-border" v-else-if="showPreview">
- <i class="fa icon-spin4 animate-spin"></i>
+ <i class="base09 icon-spin4 animate-spin"></i>
</div>
<div @click.prevent="linkClicked" class="status-content" v-html="status.statusnet_html"></div>
<div v-if='status.attachments' class='attachments'>
<attachment v-if="!hideAttachments" :status-id="status.id" :nsfw="status.nsfw" :attachment="attachment" v-for="attachment in status.attachments">
</attachment>
</div>
</div>
<div v-if="loggedIn">
<div class='status-actions'>
<div>
<a href="#" v-on:click.prevent="toggleReplying">
- <i class="fa icon-reply" :class="{'icon-reply-active': replying}"></i>
+ <i class="base09 icon-reply" :class="{'icon-reply-active': replying}"></i>
</a>
</div>
<retweet-button :status=status></retweet-button>
<favorite-button :status=status></favorite-button>
<delete-button :status=status></delete-button>
</div>
</div>
</div>
</div>
<div class="status base00-background container" v-if="replying">
<div class="reply-left"/>
<post-status-form class="reply-body" :reply-to="status.id" :attentions="status.attentions" :repliedUser="status.user" v-on:posted="toggleReplying"/>
</div>
</template>
</div>
</template>
<script src="./status.js" ></script>
<style lang="scss">
@import '../../_variables.scss';
status-text-container {
display: block;
}
.status-preview {
position: absolute;
max-width: 34em;
padding: 0.5em;
display: flex;
border-color: inherit;
border-style: solid;
border-width: 1px;
border-radius: 4px;
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
margin-top: 0.5em;
margin-left: 1em;
.avatar {
flex-shrink: 0;
width: 32px;
height: 32px;
border-radius: 50%;
}
.text {
h4 {
margin-bottom: 0.4em;
small {
font-weight: lighter;
}
}
padding: 0 0.5em 0.5em 0.5em;
}
}
.status-preview-loading {
display: block;
font-size: 2em;
min-width: 8em;
text-align: center;
}
.status-el {
hyphens: auto;
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-word;
border-left-width: 0px;
line-height: 18px;
.timeline & {
border-bottom-width: 1px;
border-bottom-style: solid;
}
.notify {
.avatar {
border-width: 3px;
border-style: solid;
}
}
.media-body {
flex: 1;
padding-left: 0.5em;
}
.user-content {
min-height: 52px;
padding-top: 1px;
}
.media-heading {
display: flex;
min-height: 1.4em;
margin-bottom: 0.3em;
small {
font-weight: lighter;
}
h4 {
margin-right: 0.4em;
}
.name-and-links {
flex: 1 0;
display: flex;
flex-wrap: wrap;
}
.replies {
flex-basis: 100%;
}
}
.source_url {
}
.expand {
margin-right: -0.3em;
}
a {
display: inline-block;
word-break: break-all;
}
.status-content {
margin: 3px 15px 4px 0;
max-height: 400px;
overflow-y: auto;
overflow-x: hidden;
img, video {
max-width: 100%;
max-height: 400px;
object-fit: contain;
}
blockquote {
margin: 0.2em 0 0.2em 2em;
font-style: italic;
}
}
p {
margin: 0;
margin-top: 0.2em;
margin-bottom: 0.5em;
}
.media-left {
margin: 0.2em 0.3em 0 0;
img {
float: right;
border-radius: 5px;
}
}
.retweet-info {
padding: 0.7em 0 0 0.6em;
.media-left {
display: flex;
i {
align-self: center;
text-align: right;
flex: 1;
padding-right: 0.3em;
}
}
}
}
.status-fadein {
animation-duration: 0.5s;
animation-name: fadein;
}
@keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.greentext {
color: green;
}
.status-conversation {
border-left-style: solid;
}
.status-actions {
padding-top: 0.15em;
width: 100%;
display: flex;
div, favorite-button {
max-width: 6em;
flex: 1;
}
}
.icon-reply:hover {
color: $blue;
}
.icon-reply-active {
color: $blue;
}
.status .avatar {
width: 48px;
height: 48px;
&.retweeted {
width: 40px;
height: 40px;
margin-right: 8px;
margin-bottom: 8px;
}
}
.status img.avatar-retweeter {
width: 24px;
height: 24px;
position: absolute;
margin-left: 24px;
margin-top: 24px;
}
.status.compact .avatar {
width: 32px;
}
.status {
padding: 0.4em 0.7em 0.45em 0.7em;
border-left: 4px rgba(255, 48, 16, 0.65);
border-left-style: inherit;
}
.status-conversation:last-child {
border-bottom: none;
}
.timeline .panel.timeline {
border-radius: 10px;
overflow: hidden;
}
.muted {
padding: 0.1em 0.4em 0.1em 0.8em;
button {
margin-left: auto;
}
.muteWords {
margin-left: 10px;
}
}
a.unmute {
display: block;
margin-left: auto;
}
.reply-left {
flex: 0;
min-width: 48px;
}
.reply-body {
flex: 1;
}
@media all and (max-width: 960px) {
.status-el {
.name-and-links {
margin-left: -0.25em;
}
}
.status {
max-width: 100%;
}
.status .avatar {
width: 40px;
height: 40px;
&.retweeted {
width: 34px;
height: 34px;
margin-right: 8px;
margin-bottom: 8px;
}
}
.status img.avatar-retweeter {
width: 22px;
height: 22px;
position: absolute;
margin-left: 18px;
margin-top: 18px;
}
}
</style>
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 74b0ff2a37..515fd253a1 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -1,86 +1,86 @@
<template>
<div class="settings panel panel-default base00-background">
<div class="panel-heading base02-background base04">
{{$t('settings.user_settings')}}
</div>
<div class="panel-body profile-edit">
<div class="setting-item">
<h3>{{$t('settings.name_bio')}}</h3>
<p>{{$t('settings.name')}}</p>
<input class='name-changer base03-border' id='username' v-model="newname" :value="user.screen_name"></input>
<p>{{$t('settings.bio')}}</p>
<textarea class="bio base03-border" v-model="newbio"></textarea>
<button :disabled='newname.length <= 0' class="btn btn-default base05 base02-background" @click="updateProfile">{{$t('general.submit')}}</button>
</div>
<div class="setting-item">
<h3>{{$t('settings.avatar')}}</h3>
<p>{{$t('settings.current_avatar')}}</p>
<img :src="user.profile_image_url_original" class="old-avatar"></img>
<p>{{$t('settings.set_new_avatar')}}</p>
<img class="new-avatar" v-bind:src="previews[0]" v-if="previews[0]">
</img>
<div>
<input type="file" @change="uploadFile(0, $event)" ></input>
</div>
- <i class="fa icon-spin4 animate-spin" v-if="uploading[0]"></i>
+ <i class="base09 icon-spin4 animate-spin" v-if="uploading[0]"></i>
<button class="btn btn-default base05 base02-background" v-else-if="previews[0]" @click="submitAvatar">{{$t('general.submit')}}</button>
</div>
<div class="setting-item">
<h3>{{$t('settings.profile_banner')}}</h3>
<p>{{$t('settings.current_profile_banner')}}</p>
<img :src="user.cover_photo" class="banner"></img>
<p>{{$t('settings.set_new_profile_banner')}}</p>
<img class="banner" v-bind:src="previews[1]" v-if="previews[1]">
</img>
<div>
<input type="file" @change="uploadFile(1, $event)" ></input>
</div>
- <i class="fa icon-spin4 animate-spin uploading" v-if="uploading[1]"></i>
+ <i class="base09 icon-spin4 animate-spin uploading" v-if="uploading[1]"></i>
<button class="btn btn-default base05 base02-background" v-else-if="previews[1]" @click="submitBanner">{{$t('general.submit')}}</button>
</div>
<div class="setting-item">
<h3>{{$t('settings.profile_background')}}</h3>
<p>{{$t('settings.set_new_profile_background')}}</p>
<img class="bg" v-bind:src="previews[2]" v-if="previews[2]">
</img>
<div>
<input type="file" @change="uploadFile(2, $event)" ></input>
</div>
- <i class="fa icon-spin4 animate-spin uploading" v-if="uploading[2]"></i>
+ <i class="base09 icon-spin4 animate-spin uploading" v-if="uploading[2]"></i>
<button class="btn btn-default base05 base02-background" v-else-if="previews[2]" @click="submitBg">{{$t('general.submit')}}</button>
</div>
</div>
</div>
</template>
<script src="./user_settings.js">
</script>
<style lang="scss">
.profile-edit {
.name-changer {
border-width: 1px;
border-style: solid;
border-radius: 5px;
padding: 0.2em 0.2em 0.2em 0.2em;
}
.name-submit {
padding: 0.2em 0.5em 0.2em 0.5em;
}
.bio {
border-width: 1px;
border-style: solid;
border-radius: 5px;
margin: 0;
}
.banner {
max-width: 400px;
border-radius: 5px;
}
.uploading {
font-size: 1.5em;
margin: 0.25em;
}
}
</style>
diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js
index 8e0258e86a..6863bd0a47 100644
--- a/src/services/style_setter/style_setter.js
+++ b/src/services/style_setter/style_setter.js
@@ -1,135 +1,138 @@
import { times } from 'lodash'
import { rgb2hex, hex2rgb } from '../color_convert/color_convert.js'
// While this is not used anymore right now, I left it in if we want to do custom
// styles that aren't just colors, so user can pick from a few different distinct
// styles as well as set their own colors in the future.
const setStyle = (href, commit) => {
/***
What's going on here?
I want to make it easy for admins to style this application. To have
a good set of default themes, I chose the system from base16
(https://chriskempson.github.io/base16/) to style all elements. They
all have the base00..0F classes. So the only thing an admin needs to
do to style Pleroma is to change these colors in that one css file.
Some default things (body text color, link color) need to be set dy-
namically, so this is done here by waiting for the stylesheet to be
loaded and then creating an element with the respective classes.
It is a bit weird, but should make life for admins somewhat easier.
***/
const head = document.head
const body = document.body
body.style.display = 'none'
const cssEl = document.createElement('link')
cssEl.setAttribute('rel', 'stylesheet')
cssEl.setAttribute('href', href)
head.appendChild(cssEl)
const setDynamic = () => {
const baseEl = document.createElement('div')
body.appendChild(baseEl)
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
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')
styleSheet.insertRule(`.base03-border { border-color: ${colors['base03']}`, 'index-max')
body.style.display = 'initial'
}
cssEl.addEventListener('load', setDynamic)
}
const setColors = (col, commit) => {
const head = document.head
const body = document.body
body.style.display = 'none'
const styleEl = document.createElement('style')
head.appendChild(styleEl)
const styleSheet = styleEl.sheet
const isDark = (col.text.r + col.text.g + col.text.b) > (col.bg.r + col.bg.g + col.bg.b)
let colors = {}
let mod = 10
if (isDark) {
mod = mod * -1
}
+
colors['base00'] = rgb2hex(col.bg.r, col.bg.g, col.bg.b) // background
colors['base01'] = rgb2hex((col.bg.r + col.fg.r) / 2, (col.bg.g + col.fg.g) / 2, (col.bg.b + col.fg.b) / 2) // hilighted bg
colors['base02'] = rgb2hex(col.fg.r, col.fg.g, col.fg.b) // panels & buttons
colors['base03'] = rgb2hex(col.fg.r - mod, col.fg.g - mod, col.fg.b - mod) // borders
colors['base04'] = rgb2hex(col.text.r + mod * 2, col.text.g + mod * 2, col.text.b + mod * 2) // faint text
colors['base05'] = rgb2hex(col.text.r, col.text.g, col.text.b) // text
colors['base06'] = rgb2hex(col.text.r - mod, col.text.g - mod, col.text.b - mod) // strong text
colors['base07'] = rgb2hex(col.text.r - mod * 2, col.text.g - mod * 2, col.text.b - mod * 2)
colors['base08'] = rgb2hex(col.link.r, col.link.g, col.link.b) // links
+ colors['base09'] = rgb2hex((col.bg.r + col.text.r) / 2, (col.bg.g + col.text.g) / 2, (col.bg.b + col.text.b) / 2) // icons
- times(9, (n) => {
- const color = colors[`base0${8 - n}`]
- styleSheet.insertRule(`.base0${8 - n} { color: ${color}`, 'index-max')
- styleSheet.insertRule(`.base0${8 - n}-background { background-color: ${color}`, 'index-max')
+ const num = 10
+ times(num, (n) => {
+ const color = colors[`base0${num - 1 - n}`]
+ styleSheet.insertRule(`.base0${num - 1 - n} { color: ${color}`, 'index-max')
+ styleSheet.insertRule(`.base0${num - 1 - n}-background { background-color: ${color}`, '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')
styleSheet.insertRule(`.base03-border { border-color: ${colors['base03']}`, 'index-max')
body.style.display = 'initial'
commit('setOption', { name: 'colors', value: colors })
commit('setOption', { name: 'customTheme', value: col })
}
const setPreset = (val, commit) => {
window.fetch('/static/styles.json')
.then((data) => data.json())
.then((themes) => {
const theme = themes[val] ? themes[val] : themes['pleroma-dark']
const bgRgb = hex2rgb(theme[1])
const fgRgb = hex2rgb(theme[2])
const textRgb = hex2rgb(theme[3])
const linkRgb = hex2rgb(theme[4])
const col = {
bg: bgRgb,
fg: fgRgb,
text: textRgb,
link: linkRgb
}
// This is a hack, this function is only called during initial load.
// We want to cancel loading the theme from config.json if we're already
// loading a theme from the persisted state.
// Needed some way of dealing with the async way of things.
// load config -> set preset -> wait for styles.json to load ->
// load persisted state -> set colors -> styles.json loaded -> set colors
if (!window.themeLoaded) {
setColors(col, commit)
}
})
}
const StyleSetter = {
setStyle,
setPreset,
setColors
}
export default StyleSetter
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Aug 9, 10:00 AM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1724427
Default Alt Text
(25 KB)
Attached To
Mode
rPUFE pleroma-fe-upstream
Attached
Detach File
Event Timeline
Log In to Comment