diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index d45584c0..469cd2c4 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -67,14 +67,26 @@ const resolveLanguage = (instanceLanguages) => {
const getInstanceConfig = async ({ store }) => {
try {
- const res = await preloadFetch('/api/v1/instance')
+ const res = await preloadFetch('/api/v2/instance')
if (res.ok) {
const data = await res.json()
- const textlimit = data.max_toot_chars
- const vapidPublicKey = data.pleroma.vapid_public_key
+ const textlimit = data.configuration.statuses.max_characters
+ const vapidPublicKey = data.configuration.vapid.public_key
store.dispatch('setInstanceOption', { name: 'textlimit', value: textlimit })
- store.dispatch('setInstanceOption', { name: 'accountApprovalRequired', value: data.approval_required })
+ const uploadLimits = {
+ general: data.configuration.media_attachments.video_size_limit,
+ avatar: "2097152",
+ background: "2097152",
+ banner: "2097152"
+ }
+ store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadLimits.general) })
+ store.dispatch('setInstanceOption', { name: 'avatarlimit', value: parseInt(uploadLimits.avatar) })
+ store.dispatch('setInstanceOption', { name: 'backgroundlimit', value: parseInt(uploadLimits.background) })
+ store.dispatch('setInstanceOption', { name: 'bannerlimit', value: parseInt(uploadLimits.banner) })
+
+ store.dispatch('setInstanceOption', { name: 'postFormats', value: data.configuration.statuses.supported_mime_types })
+ store.dispatch('setInstanceOption', { name: 'accountApprovalRequired', value: data.registrations.approval_required })
// don't override cookie if set
if (!Cookies.get('userLanguage')) {
store.dispatch('setOption', { name: 'interfaceLanguage', value: resolveLanguage(data.languages) })
@@ -83,6 +95,8 @@ const getInstanceConfig = async ({ store }) => {
if (vapidPublicKey) {
store.dispatch('setInstanceOption', { name: 'vapidPublicKey', value: vapidPublicKey })
}
+
+ resolveStaffAccounts({ store, accounts: [data.contact.account.id] })
} else {
throw (res)
}
@@ -269,42 +283,33 @@ const getNodeInfo = async ({ store }) => {
if (res.ok) {
const data = await res.json()
const metadata = data.metadata
- const features = metadata.features
store.dispatch('setInstanceOption', { name: 'name', value: metadata.nodeName })
- store.dispatch('setInstanceOption', { name: 'registrationOpen', value: data.openRegistrations })
- store.dispatch('setInstanceOption', { name: 'mediaProxyAvailable', value: features.includes('media_proxy') })
- store.dispatch('setInstanceOption', { name: 'safeDM', value: features.includes('safe_dm_mentions') })
- store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: features.includes('polls') })
- store.dispatch('setInstanceOption', { name: 'editingAvailable', value: features.includes('editing') })
+ store.dispatch('setInstanceOption', { name: 'registrationOpen', value: false }) // registration should be done through the default interface
+ store.dispatch('setInstanceOption', { name: 'mediaProxyAvailable', value: false })
+ store.dispatch('setInstanceOption', { name: 'safeDM', value: false })
+ store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: true })
+ store.dispatch('setInstanceOption', { name: 'editingAvailable', value: true })
store.dispatch('setInstanceOption', { name: 'pollLimits', value: metadata.pollLimits })
store.dispatch('setInstanceOption', { name: 'mailerEnabled', value: metadata.mailerEnabled })
- store.dispatch('setInstanceOption', { name: 'translationEnabled', value: features.includes('akkoma:machine_translation') })
+ store.dispatch('setInstanceOption', { name: 'translationEnabled', value: false }) // idk
- const uploadLimits = metadata.uploadLimits
- store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadLimits.general) })
- store.dispatch('setInstanceOption', { name: 'avatarlimit', value: parseInt(uploadLimits.avatar) })
- store.dispatch('setInstanceOption', { name: 'backgroundlimit', value: parseInt(uploadLimits.background) })
- store.dispatch('setInstanceOption', { name: 'bannerlimit', value: parseInt(uploadLimits.banner) })
- store.dispatch('setInstanceOption', { name: 'fieldsLimits', value: metadata.fieldsLimits })
+ store.dispatch('setInstanceOption', { name: 'fieldsLimits', value: 6 }) // todo: expose this on the backend
- store.dispatch('setInstanceOption', { name: 'restrictedNicknames', value: metadata.restrictedNicknames })
- store.dispatch('setInstanceOption', { name: 'postFormats', value: metadata.postFormats })
+ store.dispatch('setInstanceOption', { name: 'restrictedNicknames', value: [] })
- const suggestions = metadata.suggestions
- store.dispatch('setInstanceOption', { name: 'suggestionsEnabled', value: suggestions.enabled })
- store.dispatch('setInstanceOption', { name: 'suggestionsWeb', value: suggestions.web })
+ store.dispatch('setInstanceOption', { name: 'suggestionsEnabled', value: true })
+ store.dispatch('setInstanceOption', { name: 'suggestionsWeb', value: true })
const software = data.software
store.dispatch('setInstanceOption', { name: 'backendVersion', value: software.version })
store.dispatch('setInstanceOption', { name: 'pleromaBackend', value: software.name === 'pleroma' })
- const priv = metadata.private
- store.dispatch('setInstanceOption', { name: 'private', value: priv })
+ store.dispatch('setInstanceOption', { name: 'private', value: false })
const frontendVersion = window.___pleromafe_commit_hash
store.dispatch('setInstanceOption', { name: 'frontendVersion', value: frontendVersion })
- const federation = metadata.federation
+ const federation = {}
store.dispatch('setInstanceOption', {
name: 'tagPolicyAvailable',
@@ -314,7 +319,7 @@ const getNodeInfo = async ({ store }) => {
})
store.dispatch('setInstanceOption', { name: 'federationPolicy', value: federation })
- store.dispatch('setInstanceOption', { name: 'localBubbleInstances', value: metadata.localBubbleInstances })
+ store.dispatch('setInstanceOption', { name: 'localBubbleInstances', value: [] })
store.dispatch('setInstanceOption', {
name: 'federating',
value: typeof federation.enabled === 'undefined'
@@ -322,14 +327,11 @@ const getNodeInfo = async ({ store }) => {
: federation.enabled
})
- store.dispatch('setInstanceOption', { name: 'publicTimelineVisibility', value: metadata.publicTimelineVisibility })
- store.dispatch('setInstanceOption', { name: 'federatedTimelineAvailable', value: metadata.federatedTimelineAvailable })
+ store.dispatch('setInstanceOption', { name: 'publicTimelineVisibility', value: { bubble: false, local: true, federated: true } })
+ store.dispatch('setInstanceOption', { name: 'federatedTimelineAvailable', value: true })
const accountActivationRequired = metadata.accountActivationRequired
- store.dispatch('setInstanceOption', { name: 'accountActivationRequired', value: accountActivationRequired })
-
- const accounts = metadata.staffAccounts
- resolveStaffAccounts({ store, accounts })
+ store.dispatch('setInstanceOption', { name: 'accountActivationRequired', value: true })
} else {
throw (res)
}
diff --git a/src/components/announcement/announcement.vue b/src/components/announcement/announcement.vue
index 5f64232a..e7f6448e 100644
--- a/src/components/announcement/announcement.vue
+++ b/src/components/announcement/announcement.vue
@@ -44,20 +44,6 @@
>
{{ $t('announcements.mark_as_read_action') }}
-
- {{ $t('announcements.edit_action') }}
-
-
- {{ $t('announcements.delete_action') }}
-
-
-
-
-
{{ $t('announcements.post_form_header') }}
-
-
-
-
-
{
- this.$store.state.api.backendInteractor.fetchUser({ id: i.acct })
+ this.$store.state.api.backendInteractor.fetchUser({ id: i.id })
.then((externalUser) => {
if (!externalUser.error) {
this.$store.commit('addNewUsers', [externalUser])
diff --git a/src/components/who_to_follow_panel/who_to_follow_panel.js b/src/components/who_to_follow_panel/who_to_follow_panel.js
index 818e8bd5..a0fdabbe 100644
--- a/src/components/who_to_follow_panel/who_to_follow_panel.js
+++ b/src/components/who_to_follow_panel/who_to_follow_panel.js
@@ -9,11 +9,12 @@ function showWhoToFollow (panel, reply) {
let user = shuffled[index]
let img = user.avatar || this.$store.state.instance.defaultAvatar
let name = user.acct
+ let id = user.id
toFollow.img = img
toFollow.name = name
- panel.$store.state.api.backendInteractor.fetchUser({ id: name })
+ panel.$store.state.api.backendInteractor.fetchUser({ id })
.then((externalUser) => {
if (!externalUser.error) {
panel.$store.commit('addNewUsers', [externalUser])
diff --git a/src/modules/announcements.js b/src/modules/announcements.js
index 0f8b6d09..e9e3d4cd 100644
--- a/src/modules/announcements.js
+++ b/src/modules/announcements.js
@@ -48,7 +48,6 @@ const announcements = {
return store.rootState.api.backendInteractor.fetchAnnouncements()
}
- const all = await store.rootState.api.backendInteractor.adminFetchAnnouncements()
const visible = await store.rootState.api.backendInteractor.fetchAnnouncements()
const visibleObject = visible.reduce((a, c) => {
a[c.id] = c
@@ -56,7 +55,7 @@ const announcements = {
}, {})
const getWithinVisible = announcement => visibleObject[announcement.id]
- all.forEach(announcement => {
+ visible.forEach(announcement => {
const visibleAnnouncement = getWithinVisible(announcement)
if (!visibleAnnouncement) {
announcement.inactive = true
@@ -65,7 +64,7 @@ const announcements = {
}
})
- return all
+ return visible
}
return getAnnouncements()
diff --git a/src/modules/instance.js b/src/modules/instance.js
index 0c856352..3f598e21 100644
--- a/src/modules/instance.js
+++ b/src/modules/instance.js
@@ -35,7 +35,7 @@ const defaultState = {
hideWordFilteredPosts: false,
hidePostStats: false,
hideBotIndication: false,
- hideSiteFavicon: false,
+ hideSiteFavicon: true,
hideSiteName: false,
hideUserStats: false,
muteBotStatuses: false,
@@ -177,22 +177,19 @@ const instance = {
async getCustomEmoji ({ commit, state }) {
try {
- const res = await window.fetch('/api/v1/pleroma/emoji')
+ const res = await window.fetch('/api/v1/custom_emojis')
if (res.ok) {
const result = await res.json()
- const values = Array.isArray(result) ? Object.assign({}, ...result) : result
- const emoji = Object.entries(values).map(([key, value]) => {
- const imageUrl = value.image_url
- return {
- displayText: key,
- imageUrl: imageUrl ? state.server + imageUrl : value,
- tags: imageUrl ? value.tags.sort((a, b) => a > b ? 1 : 0) : ['utf'],
- replacement: `:${key}: `
- }
- // Technically could use tags but those are kinda useless right now,
- // should have been "pack" field, that would be more useful
- }).sort((a, b) => a.displayText.toLowerCase() > b.displayText.toLowerCase() ? 1 : -1)
- commit('setInstanceOption', { name: 'customEmoji', value: emoji })
+ const emoji = []
+ for (const emojiobj of result) {
+ emoji.push({
+ displayText: emojiobj.shortcode,
+ imageUrl: emojiobj.url,
+ tags: emojiobj.category ? [`pack:${emojiobj.category.toLowerCase()}`] : ['pack:custom'],
+ replacement: `:${emojiobj.shortcode}: `
+ })
+ }
+ commit('setInstanceOption', { name: 'customEmoji', value: emoji.sort((a, b) => a.displayText.toLowerCase() > b.displayText.toLowerCase() ? 1 : -1) })
} else {
throw (res)
}
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index 1080462c..649916a1 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -752,9 +752,9 @@ const statuses = {
)
},
fetchEmojiReactionsBy ({ rootState, commit }, id) {
- rootState.api.backendInteractor.fetchEmojiReactions({ id }).then(
- emojiReactions => {
- commit('addEmojiReactionsBy', { id, emojiReactions, currentUser: rootState.users.currentUser })
+ rootState.api.backendInteractor.fetchStatus({ id }).then(
+ status => {
+ commit('addEmojiReactionsBy', { id, emojiReactions: status.emoji_reactions, currentUser: rootState.users.currentUser })
}
)
},
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index de21ef3b..226ecc95 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -20,7 +20,7 @@ const ADMIN_USERS_URL = '/api/v1/pleroma/admin/users'
const SUGGESTIONS_URL = '/api/v1/suggestions'
const NOTIFICATION_SETTINGS_URL = '/api/pleroma/notification_settings'
const NOTIFICATION_READ_URL = '/api/v1/pleroma/notifications/read'
-const ADMIN_REPORTS_URL = '/api/v1/pleroma/admin/reports'
+const ADMIN_REPORTS_URL = '/api/v1/admin/reports'
const ADMIN_REPORT_NOTES_URL = id => `/api/v1/pleroma/admin/reports/${id}/notes`
const ADMIN_REPORT_NOTE_URL = (report, note) => `/api/v1/pleroma/admin/reports/${report}/notes/${note}`
@@ -99,9 +99,9 @@ const MASTODON_STREAMING = '/api/v1/streaming'
const MASTODON_KNOWN_DOMAIN_LIST_URL = '/api/v1/instance/peers'
const MASTODON_ANNOUNCEMENTS_URL = '/api/v1/announcements'
const MASTODON_ANNOUNCEMENTS_DISMISS_URL = id => `/api/v1/announcements/${id}/dismiss`
-const PLEROMA_EMOJI_REACTIONS_URL = id => `/api/v1/pleroma/statuses/${id}/reactions`
-const PLEROMA_EMOJI_REACT_URL = (id, emoji) => `/api/v1/pleroma/statuses/${id}/reactions/${emoji}`
-const PLEROMA_EMOJI_UNREACT_URL = (id, emoji) => `/api/v1/pleroma/statuses/${id}/reactions/${emoji}`
+const PLEROMA_EMOJI_REACTIONS_URL = id => `/api/v1/statuses/${id}/reactions`
+const PLEROMA_EMOJI_REACT_URL = (id, emoji) => `/api/v1/statuses/${id}/react/${emoji}`
+const PLEROMA_EMOJI_UNREACT_URL = (id, emoji) => `/api/v1/statuses/${id}/react/${emoji}`
const PLEROMA_BACKUP_URL = '/api/v1/pleroma/backups'
const PLEROMA_ANNOUNCEMENTS_URL = '/api/v1/pleroma/admin/announcements'
const PLEROMA_POST_ANNOUNCEMENT_URL = '/api/v1/pleroma/admin/announcements'
@@ -647,7 +647,7 @@ const getReports = ({ state, limit, page, pageSize, credentials }) => {
url = url + (args ? '?' + args : '')
return fetch(url, { headers: authHeaders(credentials) })
.then((data) => data.json())
- .then((data) => data?.reports?.map(parseReport) ?? [])
+ .then((data) => data?.map(parseReport) ?? [])
}
const updateReportStates = ({ credentials, reports }) => {
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index 4fddd875..4357973c 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -126,6 +126,34 @@ export const parseUser = (data) => {
} else {
output.role = 'member'
}
+ } else {
+ output.relationship = {
+ muting: [],
+ blocking: [],
+ followed_by: [],
+ following: []
+ }
+
+ output.rights = {
+ moderator: false,
+ admin: false
+ }
+
+ // todo: find a better way to map masto roles to akkoma roles
+ const roles = data.roles
+ if (roles) {
+ if (!roles[0]) {
+ output.role = 'member'
+ } else if (roles[0].id === "1") {
+ output.role = 'moderator'
+ output.rights.moderator = true
+ } else if (roles[0].id === "2" || roles[0].id === "3") {
+ output.role = 'admin'
+ output.rights.admin = true
+ } else {
+ output.role = 'member'
+ }
+ }
}
if (data.source) {
@@ -297,6 +325,9 @@ export const parseStatus = (data) => {
} else {
output.text = data.content
output.summary = data.spoiler_text
+ output.emoji_reactions = data.reactions
+ // todo: properly check if post is visible
+ output.parent_visible = true
}
if (data.akkoma) {
@@ -405,14 +436,16 @@ export const parseStatus = (data) => {
export const parseNotification = (data) => {
const mastoDict = {
'favourite': 'like',
- 'reblog': 'repeat'
+ 'reblog': 'repeat',
+ 'reaction': 'pleroma:emoji_reaction'
}
const masto = !data.hasOwnProperty('ntype')
const output = {}
if (masto) {
output.type = mastoDict[data.type] || data.type
- output.seen = data.pleroma.is_seen
+ // todo: figure out how to tell if a notification has been seen or not
+ output.seen = true
if (data.status) {
output.status = isStatusNotification(output.type) ? parseStatus(data.status) : null
output.action = output.status // TODO: Refactor, this is unneeded
@@ -443,15 +476,12 @@ export const parseNotification = (data) => {
export const parseReport = (data) => {
const report = {}
- report.account = parseUser(data.account)
- report.actor = parseUser(data.actor)
+ report.account = parseUser(data.target_account.account)
+ report.actor = parseUser(data.account.account)
report.statuses = data.statuses.map(parseStatus)
- report.notes = data.notes.map(note => {
- note.user = parseUser(note.user)
- return note
- })
- report.state = data.state
- report.content = data.content
+ report.notes = []
+ report.state = data.action_taken ? "closed" : "open"
+ report.content = data.comment
report.created_at = data.created_at
report.id = data.id
diff --git a/src/services/new_api/oauth.js b/src/services/new_api/oauth.js
index 3c8e64bd..9f7010ac 100644
--- a/src/services/new_api/oauth.js
+++ b/src/services/new_api/oauth.js
@@ -10,9 +10,9 @@ export const getOrCreateApp = ({ clientId, clientSecret, instance, commit }) =>
const url = `${instance}/api/v1/apps`
const form = new window.FormData()
- form.append('client_name', `PleromaFE_${window.___pleromafe_commit_hash}_${(new Date()).toISOString()}`)
+ form.append('client_name', "AkkomaFE")
form.append('redirect_uris', REDIRECT_URI)
- form.append('scopes', 'read write follow push admin')
+ form.append('scopes', 'read write follow push admin:read admin:write')
return window.fetch(url, {
method: 'POST',
@@ -28,7 +28,7 @@ const login = ({ instance, clientId }) => {
response_type: 'code',
client_id: clientId,
redirect_uri: REDIRECT_URI,
- scope: 'read write follow push admin'
+ scope: 'read write follow push admin:read admin:write'
}
const dataString = reduce(data, (acc, v, k) => {
diff --git a/static/config.json b/static/config.json
index b1d412e7..b4f8feb7 100644
--- a/static/config.json
+++ b/static/config.json
@@ -1,6 +1,6 @@
{
"alwaysShowSubjectInput": true,
- "background": "/static/aurora_borealis.jpg",
+ "background": "/static/wdwskyboxbanner.png",
"collapseMessageWithSubject": false,
"greentext": false,
"hideFilteredStatuses": false,
@@ -8,15 +8,15 @@
"hidePostStats": false,
"hideSitename": false,
"hideUserStats": false,
- "loginMethod": "password",
- "logo": "/static/logo.svg",
+ "loginMethod": "token",
+ "logo": "/static/logo.png",
"logoMargin": ".1em",
- "logoMask": true,
+ "logoMask": false,
"logoLeft": false,
"nsfwCensorImage": "",
"postContentType": "text/plain",
"redirectRootLogin": "/main/friends",
- "redirectRootNoLogin": "/main/all",
+ "redirectRootNoLogin": "/main/public",
"showFeaturesPanel": true,
"showInstanceSpecificPanel": false,
"sidebarRight": false,
diff --git a/static/logo.png b/static/logo.png
new file mode 100644
index 00000000..194bcd05
Binary files /dev/null and b/static/logo.png differ
diff --git a/static/terms-of-service.html b/static/terms-of-service.html
index 46633629..8302265a 100644
--- a/static/terms-of-service.html
+++ b/static/terms-of-service.html
@@ -1,5 +1,3 @@
-Terms of Service
+This is Akkoma-FE modified to work on top of Mastodon/Chuckya. Note that while most of it should work fine, there are still a few differences between Akkoma and Mastodon that may cause things to break.
-
This is a placeholder, overwrite this by putting a file at
$STATIC_DIR/static/terms-of-service.html
-
-
See the Static Directory docs for more info.
\ No newline at end of file
+Source code: https://akkoma.dev/esm/akkoma-fe
diff --git a/static/wdwskyboxbanner.png b/static/wdwskyboxbanner.png
new file mode 100644
index 00000000..08895537
Binary files /dev/null and b/static/wdwskyboxbanner.png differ