summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis <6653109+artonge@users.noreply.github.com>2023-04-11 11:42:12 +0200
committerGitHub <noreply@github.com>2023-04-11 11:42:12 +0200
commit4d056fe998e227da2e3f486679e2f2d39cb1ce34 (patch)
treee92331081e9e7693aff1ec60a8184b992f365698
parent29a3d2e07873e596289c2b93059845ce03112b44 (diff)
parent764bfcc3091ab38dc60546357ec3953bbc41b17f (diff)
Merge pull request #1719 from nextcloud/artonge/fix/fixes
Tiny fixes all around
-rw-r--r--lib/AppInfo/Application.php2
-rw-r--r--src/components/Composer/Composer.vue9
-rw-r--r--src/components/ProfileInfo.vue9
-rw-r--r--src/components/TimelineAvatar.vue7
-rw-r--r--src/components/TimelineEntry.vue34
-rw-r--r--src/components/TimelineList.vue2
-rw-r--r--src/components/TimelinePost.vue7
-rw-r--r--src/dashboard.js5
-rw-r--r--src/main.js5
-rw-r--r--src/services/notifications.js32
-rw-r--r--src/views/Dashboard.vue69
-rw-r--r--src/views/ProfilePageIntegration.vue12
12 files changed, 102 insertions, 91 deletions
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index b7fac6c7..7ef42a73 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -60,7 +60,7 @@ class Application extends App implements IBootstrap {
$context->registerSearchProvider(UnifiedSearchProvider::class);
$context->registerWellKnownHandler(WebfingerHandler::class);
$context->registerEventListener(BeforeTemplateRenderedEvent::class, ProfileSectionListener::class);
-// $context->registerDashboardWidget(SocialWidget::class);
+ $context->registerDashboardWidget(SocialWidget::class);
}
public function boot(IBootContext $context): void {
diff --git a/src/components/Composer/Composer.vue b/src/components/Composer/Composer.vue
index 0b43ce36..14b167df 100644
--- a/src/components/Composer/Composer.vue
+++ b/src/components/Composer/Composer.vue
@@ -169,13 +169,13 @@ export default {
},
defaultVisibility: {
type: String,
- default: localStorage.getItem('social.lastPostType') || 'followers',
+ default: undefined,
},
},
data() {
return {
statusContent: '',
- visibility: this.defaultVisibility,
+ visibility: this.defaultVisibility || localStorage.getItem('social.lastPostType') || 'followers',
loading: false,
/** @type {Object<string, LocalAttachment>} */
attachments: {},
@@ -301,14 +301,14 @@ export default {
* @param {import('../../types/Mastodon.js').Account} account
*/
prefillMessageWithMention(account) {
- if (!this.statusIsEmpty) {
+ if (!this.statusIsEmpty || this.$refs.composerInput === undefined) {
return
}
this.$refs.composerInput.innerHTML = `
<span class="mention" contenteditable="false">
<a href="${account.url}" target="_blank">
- <img src="${!account.acct.includes('@') ? generateUrl(`/avatar/${account.username}/32`) : generateUrl(`apps/social/api/v1/global/actor/avatar?id=${account.acct}`)}"/>
+ <img src="${account.avatar}"/>
@${account.acct}
</a>
</span>&nbsp;`
@@ -413,6 +413,7 @@ export default {
this.loading = false
this.replyTo = null
this.$refs.composerInput.innerText = ''
+ this.updateStatusContent()
this.attachments = {}
this.$store.dispatch('refreshTimeline')
}
diff --git a/src/components/ProfileInfo.vue b/src/components/ProfileInfo.vue
index fecc1a6a..6ebdbead 100644
--- a/src/components/ProfileInfo.vue
+++ b/src/components/ProfileInfo.vue
@@ -27,7 +27,7 @@
:disable-tooltip="true"
:size="128" />
<NcAvatar v-else
- :url="avatarUrl"
+ :url="accountInfo.avatar"
:disable-tooltip="true"
:size="128" />
<h2>{{ displayName }}</h2>
@@ -57,6 +57,9 @@
{{ t('social', 'Website') }}: <a :href="website.value">{{ website.value }}<OpenInNew :size="15" /></a>
</p>
+ <!-- Hack to render note safely -->
+ <MessageContent v-if="accountInfo.note" class="user-profile__note" :item="{content: accountInfo.note, tag: [], mentions: []}" />
+
<FollowButton class="user-profile__info" :account="accountInfo.acct" :uid="uid" />
<NcButton v-if="serverData.public"
class="user-profile__info primary"
@@ -158,6 +161,10 @@ export default {
}
+ &__note {
+ text-align: start;
+ }
+
&__sections {
display: flex;
diff --git a/src/components/TimelineAvatar.vue b/src/components/TimelineAvatar.vue
index cb04bdc4..11aeb658 100644
--- a/src/components/TimelineAvatar.vue
+++ b/src/components/TimelineAvatar.vue
@@ -43,11 +43,14 @@ export default {
}
</script>
-<style scoped>
+<style scoped lang='scss'>
.post-avatar {
- position: relative;
padding: 5px 10px 10px 5px;
height: 52px;
width: 52px;
+
+ .avatardiv {
+ position: static;
+ }
}
</style>
diff --git a/src/components/TimelineEntry.vue b/src/components/TimelineEntry.vue
index 1da0222d..2c641ebe 100644
--- a/src/components/TimelineEntry.vue
+++ b/src/components/TimelineEntry.vue
@@ -1,5 +1,5 @@
<template>
- <div :class="['timeline-entry', hasHeader ? 'with-header' : '']">
+ <li :class="['timeline-entry', hasHeader ? 'with-header' : '']">
<div v-if="isNotification" class="notification">
<Bell :size="22" />
<span class="notification-action">
@@ -30,15 +30,16 @@
:type="type" />
</div>
</template>
- </div>
+ </li>
</template>
<script>
+import Bell from 'vue-material-design-icons/Bell.vue'
+import { translate } from '@nextcloud/l10n'
import TimelinePost from './TimelinePost.vue'
import TimelineAvatar from './TimelineAvatar.vue'
import UserEntry from './UserEntry.vue'
-import Bell from 'vue-material-design-icons/Bell.vue'
-import { translate } from '@nextcloud/l10n'
+import { notificationSummary } from '../services/notifications.js'
export default {
name: 'TimelineEntry',
@@ -102,30 +103,7 @@ export default {
* @return {string}
*/
actionSummary() {
- switch (this.notification.type) {
- case 'mention':
- return t('social', '{account} mentioned you', { account: this.notification.account.acct })
- case 'status':
- return t('social', '{account} posted a status', { account: this.notification.account.acct })
- case 'reblog':
- return t('social', '{account} boosted your post', { account: this.notification.account.acct })
- case 'follow':
- return t('social', '{account} started to follow you', { account: this.notification.account.acct })
- case 'follow_request':
- return t('social', '{account} requested to follow you', { account: this.notification.account.acct })
- case 'favourite':
- return t('social', '{account} liked your post', { account: this.notification.account.acct })
- case 'poll':
- return t('social', '{account} ended the poll', { account: this.notification.account.acct })
- case 'update':
- return t('social', '{account} edited a status', { account: this.notification.account.acct })
- case 'admin.sign_up':
- return t('social', '{account} signed up', { account: this.notification.account.acct })
- case 'admin.report':
- return t('social', '{account} filed a report', { account: this.notification.account.acct })
- default:
- return ''
- }
+ return notificationSummary(this.notification)
},
},
methods: {
diff --git a/src/components/TimelineList.vue b/src/components/TimelineList.vue
index 9d31b193..0141063c 100644
--- a/src/components/TimelineList.vue
+++ b/src/components/TimelineList.vue
@@ -22,7 +22,7 @@
<template>
<div class="social__timeline">
- <transition-group name="list" tag="div">
+ <transition-group name="list" tag="ul">
<TimelineEntry v-for="entry in timeline"
:key="entry.id"
:item="entry"
diff --git a/src/components/TimelinePost.vue b/src/components/TimelinePost.vue
index e04e70d7..5d504788 100644
--- a/src/components/TimelinePost.vue
+++ b/src/components/TimelinePost.vue
@@ -44,7 +44,7 @@
</span>
</template>
</NcButton>
- <NcButton v-if="item.visibility === 'public' || item.visibility === 'followers'"
+ <NcButton v-if="item.visibility === 'public' || item.visibility === 'unlisted'"
:title="t('social', 'Boost')"
type="tertiary-no-background"
@click="boost">
@@ -208,10 +208,10 @@ export default {
getSinglePostTimeline(e) {
// Display internal or external post
if (!this.isLocal) {
+ // TODO - fix
if (this.type === 'Note') {
window.open(this.item.id)
} else if (this.type === 'Announce') {
- // TODO
window.open(this.item.object)
} else {
logger.warn("Don't know what to do with posts of type " + this.type, { post: this.item })
@@ -269,7 +269,6 @@ export default {
padding: 4px 8px;
font-size: 15px;
line-height: 1.6em;
- position: relative;
border-radius: 8px;
::v-deep a.widget-default {
@@ -304,7 +303,7 @@ export default {
}
.post-visibility {
- opacity: 0.5;
+ color: var(--color-text-lighter);
background-position: right;
}
diff --git a/src/dashboard.js b/src/dashboard.js
index bb0adbc5..56a6b1a3 100644
--- a/src/dashboard.js
+++ b/src/dashboard.js
@@ -26,8 +26,11 @@ Vue.prototype.OC = window.OC
document.addEventListener('DOMContentLoaded', function() {
OCA.Dashboard.register('social_notifications', (el, { widget }) => {
const View = Vue.extend(Dashboard)
+ /* eslint-disable-next-line no-new */
new View({
propsData: { title: widget.title },
- }).$mount(el)
+ el,
+ name: 'SocialDashboard',
+ })
})
})
diff --git a/src/main.js b/src/main.js
index 57ea3e25..98f7eb92 100644
--- a/src/main.js
+++ b/src/main.js
@@ -57,7 +57,10 @@ Vue.use(VueMasonry)
/* eslint-disable-next-line no-new */
new Vue({
+ el: '#content',
+ // eslint-disable-next-line vue/match-component-file-name
+ name: 'SocialRoot',
router,
render: h => h(App),
store,
-}).$mount('#content')
+})
diff --git a/src/services/notifications.js b/src/services/notifications.js
new file mode 100644
index 00000000..44a2b7bc
--- /dev/null
+++ b/src/services/notifications.js
@@ -0,0 +1,32 @@
+import { translate } from '@nextcloud/l10n'
+
+/**
+ * @param {import("../types/Mastodon").Notification} notification
+ * @return {string}
+ */
+export function notificationSummary(notification) {
+ switch (notification.type) {
+ case 'mention':
+ return translate('social', '{account} mentioned you', { account: notification.account.acct })
+ case 'status':
+ return translate('social', '{account} posted a status', { account: notification.account.acct })
+ case 'reblog':
+ return translate('social', '{account} boosted your post', { account: notification.account.acct })
+ case 'follow':
+ return translate('social', '{account} started to follow you', { account: notification.account.acct })
+ case 'follow_request':
+ return translate('social', '{account} requested to follow you', { account: notification.account.acct })
+ case 'favourite':
+ return translate('social', '{account} liked your post', { account: notification.account.acct })
+ case 'poll':
+ return translate('social', '{account} ended the poll', { account: notification.account.acct })
+ case 'update':
+ return translate('social', '{account} edited a status', { account: notification.account.acct })
+ case 'admin.sign_up':
+ return translate('social', '{account} signed up', { account: notification.account.acct })
+ case 'admin.report':
+ return translate('social', '{account} filed a report', { account: notification.account.acct })
+ default:
+ return ''
+ }
+}
diff --git a/src/views/Dashboard.vue b/src/views/Dashboard.vue
index dab943e9..adc155b8 100644
--- a/src/views/Dashboard.vue
+++ b/src/views/Dashboard.vue
@@ -47,6 +47,7 @@ import { generateUrl } from '@nextcloud/router'
import { showError } from '@nextcloud/dialogs'
import NcDashboardWidget from '@nextcloud/vue/dist/Components/NcDashboardWidget.js'
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
+import { notificationSummary } from '../services/notifications.js'
export default {
name: 'Dashboard',
@@ -121,25 +122,19 @@ export default {
},
methods: {
- fetchNotifications() {
- const req = {
- params: {
- limit: 10,
- },
- }
- const url = generateUrl('/apps/social/api/v1/stream/notifications')
- // TODO check why 'since' param is in fact 'until'
- /* if (this.lastDate) {
- req.params.since = this.lastTimestamp,
- } */
- axios.get(url, req).then((response) => {
- if (response.data?.result) {
- this.processNotifications(response.data.result)
+ async fetchNotifications() {
+ const url = generateUrl('apps/social/api/v1/notifications')
+
+ try {
+
+ const response = await axios.get(url)
+ if (response.data) {
+ this.processNotifications(response.data)
this.state = 'ok'
} else {
this.state = 'error'
}
- }).catch((error) => {
+ } catch (error) {
clearInterval(this.loop)
if (error.response?.status && error.response.status >= 400) {
showError(t('social', 'Failed to get Social notifications'))
@@ -148,8 +143,9 @@ export default {
// there was an error in notif processing
console.error(error)
}
- })
+ }
},
+ /** @param {import('../types/Mastodon.js').Notification[]} newNotifications */
processNotifications(newNotifications) {
if (this.lastTimestamp !== 0) {
// just add those which are more recent than our most recent one
@@ -166,55 +162,46 @@ export default {
this.notifications = this.filter(newNotifications)
}
},
+ /** @param {import('../types/Mastodon.js').Notification[]} notifications */
filter(notifications) {
return notifications
- // TODO check if we need to filter
- /* return notifications.filter((n) => {
- return (n.type === 'something' || n.subtype === 'somethingElse')
- }) */
},
+ /** @param {import('../types/Mastodon.js').Notification} n */
getMainText(n) {
- if (n.subtype === 'Follow') {
- return t('social', '{account} is following you', { account: this.getActorName(n) })
- }
- if (n.subtype === 'Like') {
- return t('social', '{account} liked your post', { account: this.getActorName(n) })
- }
+ return notificationSummary(n)
},
+ /** @param {import('../types/Mastodon.js').Notification} n */
getAvatarUrl(n) {
- return undefined
- // TODO get external and internal avatars
- /* return this.getActorAccountName(n)
- ? generateUrl('???')
- : undefined */
+ return n.account.avatar
},
+ /** @param {import('../types/Mastodon.js').Notification} n */
getActorName(n) {
- return n.actor_info && n.actor_info.type === 'Person' && n.actor_info.preferredUsername
- ? n.actor_info.preferredUsername
- : ''
+ return n.account.display_name
},
+ /** @param {import('../types/Mastodon.js').Notification} n */
getActorAccountName(n) {
- return n.actor_info && n.actor_info.type === 'Person' && n.actor_info.account
- ? n.actor_info.account
- : ''
+ return n.account.acct
},
+ /** @param {import('../types/Mastodon.js').Notification} n */
getNotificationTarget(n) {
- if (n.subtype === 'Follow') {
+ if (n.type === 'follow') {
return generateUrl('/apps/social/@' + this.getActorAccountName(n) + '/')
}
return this.showMoreUrl
},
+ /** @param {import('../types/Mastodon.js').Notification} n */
getSubline(n) {
- if (n.subtype === 'Follow') {
+ if (n.type === 'follow') {
return this.getActorAccountName(n)
}
- if (n.subtype === 'Like') {
+ if (n.type === 'favourite') {
return this.getActorAccountName(n)
}
return ''
},
+ /** @param {import('../types/Mastodon.js').Notification} n */
getNotificationTypeImage(n) {
- if (n.subtype === 'Follow') {
+ if (n.type === 'follow') {
return generateUrl('/svg/social/add_user')
}
return ''
diff --git a/src/views/ProfilePageIntegration.vue b/src/views/ProfilePageIntegration.vue
index 769ccd1e..8771a19e 100644
--- a/src/views/ProfilePageIntegration.vue
+++ b/src/views/ProfilePageIntegration.vue
@@ -1,7 +1,7 @@
<template>
<div>
<h2>Social</h2>
- <transition-group name="list" tag="div">
+ <transition-group name="list" tag="ul">
<TimelineEntry v-for="entry in timeline"
:key="entry.id"
:item="entry" />
@@ -42,16 +42,14 @@ export default {
beforeMount() {
const uid = this.userId
- axios.get(generateUrl(`apps/social/api/v1/account/${uid}/info`)).then((response) => {
- this.accountInfo = response.data.result.account
+ axios.get(generateUrl(`apps/social/api/v1/global/account/info?account=${uid}`)).then(({ data }) => {
+ this.accountInfo = data
logger.log(this.accountInfo)
})
- const since = Math.floor(Date.now() / 1000) + 1
-
- axios.get(generateUrl(`apps/social/api/v1/account/${uid}/stream?limit=25&since=${since}`)).then(({ data }) => {
+ axios.get(generateUrl(`apps/social/api/v1/accounts/${uid}/statuses`)).then(({ data }) => {
+ this.timeline = data
logger.log(this.timeline)
- this.timeline = data.result
})
},
}