Merge remote-tracking branch 'origin/develop' into shigusegubu
* origin/develop: changelong Fix pinned statuses and perhaps some other stuff update changelog Remove title from index.html, title is now from server generated meta changelog mention fix emoji not working in profile field names change method of fix to rounding changelog prevent call to scroll if the value doesn't change because firefox is stupid Update CHANGELOG.md wrap react button icon to a span to fix popover overflow Update CHANGELOG.md to match master change favicon dimensions for high res, add handling when favicon isn't available remove the favicon changes make badge just a ball, make it use theming add favicon badge for unread notifs
This commit is contained in:
commit
d8ac75f58a
10 changed files with 116 additions and 21 deletions
26
CHANGELOG.md
26
CHANGELOG.md
|
@ -3,17 +3,29 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
|
||||
## [Unreleased]
|
||||
### Fixed
|
||||
- Fixed the occasional bug where screen would scroll 1px when typing into a reply form
|
||||
- Fixed custom emoji not working in profile field names
|
||||
- Fixed pinned statuses not appearing in user profiles
|
||||
|
||||
|
||||
## [2.2.1] - 2020-11-11
|
||||
### Fixed
|
||||
- Fixed regression in react popup alignment and overflowing
|
||||
|
||||
|
||||
## [2.2.0] - 2020-11-06
|
||||
### Added
|
||||
- New option to optimize timeline rendering to make the site more responsive (enabled by default)
|
||||
- New instance option `logoLeft` to move logo to the left side in desktop nav bar
|
||||
- Import/export a muted users
|
||||
- Proper handling of deletes when using websocket streaming
|
||||
- Added optimistic chat message sending, so you can start writing next message before the previous one has been sent
|
||||
- Added a small red badge to the favicon when there's unread notifications
|
||||
|
||||
### Fixed
|
||||
- Fixed chats list not updating its order when new messages come in
|
||||
- Fixed chat messages sometimes getting lost when you receive a message at the same time
|
||||
- Fixed clicking NSFW hider through status popover
|
||||
- Fixed chat-view back button being hard to click
|
||||
- Fixed fresh chat notifications being cleared immediately while leaving the chat view and not having time to actually see the messages
|
||||
|
@ -29,6 +41,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Logo is now clickable
|
||||
- Changed default logo to SVG version
|
||||
|
||||
|
||||
## [2.1.2] - 2020-09-17
|
||||
### Fixed
|
||||
- Fixed chats list not updating its order when new messages come in
|
||||
- Fixed chat messages sometimes getting lost when you receive a message at the same time
|
||||
|
||||
|
||||
## [2.1.1] - 2020-09-08
|
||||
### Changed
|
||||
- Polls will be hidden with status content if "Collapse posts with subjects" is enabled and the post is collapsed.
|
||||
|
@ -154,8 +173,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Ability to change user's email
|
||||
- About page
|
||||
- Added remote user redirect
|
||||
- Bookmarks
|
||||
|
||||
### Changed
|
||||
- changed the way fading effects for user profile/long statuses works, now uses css-mask instead of gradient background hacks which weren't exactly compatible with semi-transparent themes
|
||||
|
||||
### Fixed
|
||||
- improved hotkey behavior on autocomplete popup
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
|
||||
<title>Pleroma</title>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/ngs/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/ngs/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/ngs/favicon-16x16.png">
|
||||
|
|
|
@ -7,6 +7,7 @@ import { getOrCreateApp, getClientToken } from '../services/new_api/oauth.js'
|
|||
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
|
||||
import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js'
|
||||
import { applyTheme } from '../services/style_setter/style_setter.js'
|
||||
import FaviconService from '../services/favicon_service/favicon_service.js'
|
||||
|
||||
let staticInitialResults = null
|
||||
|
||||
|
@ -326,6 +327,8 @@ const afterStoreSetup = async ({ store, i18n }) => {
|
|||
const width = windowWidth()
|
||||
store.dispatch('setMobileLayout', width <= 800)
|
||||
|
||||
FaviconService.initFaviconService()
|
||||
|
||||
const overrides = window.___pleromafe_dev_overrides || {}
|
||||
const server = (typeof overrides.target !== 'undefined') ? overrides.target : window.location.origin
|
||||
store.dispatch('setInstanceOption', { name: 'server', value: server })
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
filteredNotificationsFromStore,
|
||||
unseenNotificationsFromStore
|
||||
} from '../../services/notification_utils/notification_utils.js'
|
||||
import FaviconService from '../../services/favicon_service/favicon_service.js'
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
|
@ -75,8 +76,10 @@ const Notifications = {
|
|||
watch: {
|
||||
unseenCountTitle (count) {
|
||||
if (count > 0) {
|
||||
FaviconService.drawFaviconBadge()
|
||||
this.$store.dispatch('setPageTitle', `(${count})`)
|
||||
} else {
|
||||
FaviconService.clearFaviconBadge()
|
||||
this.$store.dispatch('setPageTitle', '')
|
||||
}
|
||||
}
|
||||
|
|
|
@ -531,7 +531,7 @@ const PostStatusForm = {
|
|||
!(isFormBiggerThanScroller &&
|
||||
this.$refs.textarea.selectionStart !== this.$refs.textarea.value.length)
|
||||
const totalDelta = shouldScrollToBottom ? bottomChangeDelta : 0
|
||||
const targetScroll = currentScroll + totalDelta
|
||||
const targetScroll = Math.round(currentScroll + totalDelta)
|
||||
|
||||
if (scrollerRef === window) {
|
||||
scrollerRef.scroll(0, targetScroll)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
placement="top"
|
||||
:offset="{ y: 5 }"
|
||||
class="react-button-popover"
|
||||
:bound-to="{ x: 'container' }"
|
||||
>
|
||||
<div
|
||||
slot="content"
|
||||
|
@ -37,12 +38,13 @@
|
|||
<div class="reaction-bottom-fader" />
|
||||
</div>
|
||||
</div>
|
||||
<FAIcon
|
||||
slot="trigger"
|
||||
class="fa-scale-110 fa-old-padding add-reaction-button"
|
||||
:icon="['far', 'smile-beam']"
|
||||
:title="$t('tool_tip.add_reaction')"
|
||||
/>
|
||||
<span slot="trigger">
|
||||
<FAIcon
|
||||
class="fa-scale-110 fa-old-padding add-reaction-button"
|
||||
:icon="['far', 'smile-beam']"
|
||||
:title="$t('tool_tip.add_reaction')"
|
||||
/>
|
||||
</span>
|
||||
</Popover>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -20,14 +20,13 @@
|
|||
:key="index"
|
||||
class="user-profile-field"
|
||||
>
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
<dt
|
||||
:title="user.fields_text[index].name"
|
||||
class="user-profile-field-name"
|
||||
@click.prevent="linkClicked"
|
||||
>
|
||||
{{ field.name }}
|
||||
</dt>
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
v-html="field.name"
|
||||
/>
|
||||
<dd
|
||||
:title="user.fields_text[index].value"
|
||||
class="user-profile-field-value"
|
||||
|
|
|
@ -137,11 +137,11 @@ export const mutations = {
|
|||
},
|
||||
saveFriendIds (state, { id, friendIds }) {
|
||||
const user = state.usersObject[id]
|
||||
user.friendIds = uniq(concat(user.friendIds, friendIds))
|
||||
user.friendIds = uniq(concat(user.friendIds || [], friendIds))
|
||||
},
|
||||
saveFollowerIds (state, { id, followerIds }) {
|
||||
const user = state.usersObject[id]
|
||||
user.followerIds = uniq(concat(user.followerIds, followerIds))
|
||||
user.followerIds = uniq(concat(user.followerIds || [], followerIds))
|
||||
},
|
||||
// Because frontend doesn't have a reason to keep these stuff in memory
|
||||
// outside of viewing someones user profile.
|
||||
|
@ -202,7 +202,9 @@ export const mutations = {
|
|||
},
|
||||
setPinnedToUser (state, status) {
|
||||
const user = state.usersObject[status.user.id]
|
||||
user.pinnedStatusIds = user.pinnedStatusIds || []
|
||||
const index = user.pinnedStatusIds.indexOf(status.id)
|
||||
|
||||
if (status.pinned && index === -1) {
|
||||
user.pinnedStatusIds.push(status.id)
|
||||
} else if (!status.pinned && index !== -1) {
|
||||
|
|
|
@ -2,6 +2,15 @@ import escape from 'escape-html'
|
|||
import parseLinkHeader from 'parse-link-header'
|
||||
import { isStatusNotification } from '../notification_utils/notification_utils.js'
|
||||
|
||||
/** NOTICE! **
|
||||
* Do not initialize UI-generated data here.
|
||||
* It will override existing data.
|
||||
*
|
||||
* i.e. user.pinnedStatusIds was set to [] here
|
||||
* UI code would update it with data but upon next user fetch
|
||||
* it would be reverted back to []
|
||||
*/
|
||||
|
||||
const qvitterStatusType = (status) => {
|
||||
if (status.is_post_verb) {
|
||||
return 'status'
|
||||
|
@ -53,7 +62,7 @@ export const parseUser = (data) => {
|
|||
output.fields = data.fields
|
||||
output.fields_html = data.fields.map(field => {
|
||||
return {
|
||||
name: addEmojis(field.name, data.emojis),
|
||||
name: addEmojis(escape(field.name), data.emojis),
|
||||
value: addEmojis(field.value, data.emojis)
|
||||
}
|
||||
})
|
||||
|
@ -173,9 +182,6 @@ export const parseUser = (data) => {
|
|||
output.locked = data.locked
|
||||
output.followers_count = data.followers_count
|
||||
output.statuses_count = data.statuses_count
|
||||
output.friendIds = []
|
||||
output.followerIds = []
|
||||
output.pinnedStatusIds = []
|
||||
|
||||
if (data.pleroma) {
|
||||
output.follow_request_count = data.pleroma.follow_request_count
|
||||
|
|
61
src/services/favicon_service/favicon_service.js
Normal file
61
src/services/favicon_service/favicon_service.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
import { find } from 'lodash'
|
||||
|
||||
const createFaviconService = () => {
|
||||
let favimg, favcanvas, favcontext, favicon
|
||||
const faviconWidth = 128
|
||||
const faviconHeight = 128
|
||||
const badgeRadius = 32
|
||||
|
||||
const initFaviconService = () => {
|
||||
const nodes = document.getElementsByTagName('link')
|
||||
favicon = find(nodes, node => node.rel === 'icon')
|
||||
if (favicon) {
|
||||
favcanvas = document.createElement('canvas')
|
||||
favcanvas.width = faviconWidth
|
||||
favcanvas.height = faviconHeight
|
||||
favimg = new Image()
|
||||
favimg.src = favicon.href
|
||||
favcontext = favcanvas.getContext('2d')
|
||||
}
|
||||
}
|
||||
|
||||
const isImageLoaded = (img) => img.complete && img.naturalHeight !== 0
|
||||
|
||||
const clearFaviconBadge = () => {
|
||||
if (!favimg || !favcontext || !favicon) return
|
||||
|
||||
favcontext.clearRect(0, 0, faviconWidth, faviconHeight)
|
||||
if (isImageLoaded(favimg)) {
|
||||
favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight)
|
||||
}
|
||||
favicon.href = favcanvas.toDataURL('image/png')
|
||||
}
|
||||
|
||||
const drawFaviconBadge = () => {
|
||||
if (!favimg || !favcontext || !favcontext) return
|
||||
|
||||
clearFaviconBadge()
|
||||
|
||||
const style = getComputedStyle(document.body)
|
||||
const badgeColor = `${style.getPropertyValue('--badgeNotification') || 'rgb(240, 100, 100)'}`
|
||||
|
||||
if (isImageLoaded(favimg)) {
|
||||
favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight)
|
||||
}
|
||||
favcontext.fillStyle = badgeColor
|
||||
favcontext.beginPath()
|
||||
favcontext.arc(faviconWidth - badgeRadius, badgeRadius, badgeRadius, 0, 2 * Math.PI, false)
|
||||
favcontext.fill()
|
||||
favicon.href = favcanvas.toDataURL('image/png')
|
||||
}
|
||||
|
||||
return {
|
||||
initFaviconService,
|
||||
clearFaviconBadge,
|
||||
drawFaviconBadge
|
||||
}
|
||||
}
|
||||
|
||||
const FaviconService = createFaviconService()
|
||||
|
||||
export default FaviconService
|
Loading…
Add table
Reference in a new issue