From ef2585e32b546722f2157bd6203701deb495d2e9 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Fri, 11 Jan 2019 02:40:17 +0300 Subject: Remove all explicit and implicit conversions of statusId to number, changed explicit ones so that they convert them to string --- src/components/conversation/conversation.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/components/conversation/conversation.js') diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index 9d9f7bbe..95432248 100644 --- a/src/components/conversation/conversation.js +++ b/src/components/conversation/conversation.js @@ -32,7 +32,7 @@ const conversation = { replies () { let i = 1 return reduce(this.conversation, (result, {id, in_reply_to_status_id}) => { - const irid = Number(in_reply_to_status_id) + const irid = String(in_reply_to_status_id) if (irid) { result[irid] = result[irid] || [] result[irid].push({ @@ -69,7 +69,7 @@ const conversation = { } }, getReplies (id) { - id = Number(id) + id = String(id) return this.replies[id] || [] }, focused (id) { @@ -80,7 +80,7 @@ const conversation = { } }, setHighlight (id) { - this.highlight = Number(id) + this.highlight = String(id) } } } -- cgit v1.2.3-70-g09d2 From 519f49e29b38e568727dd7f59618002459a64d64 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 13 Jan 2019 22:07:55 +0300 Subject: separated normalization into a another file, removed catchall and added more stuff --- src/components/conversation/conversation.js | 9 +- src/services/api/api.service.js | 105 ++---------------- .../status_normalizer/status_normalizer.service.js | 118 +++++++++++++++++++++ 3 files changed, 131 insertions(+), 101 deletions(-) create mode 100644 src/services/status_normalizer/status_normalizer.service.js (limited to 'src/components/conversation/conversation.js') diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index 9d9f7bbe..7bad14a5 100644 --- a/src/components/conversation/conversation.js +++ b/src/components/conversation/conversation.js @@ -1,9 +1,8 @@ import { reduce, filter, sortBy } from 'lodash' -import { statusType } from '../../modules/statuses.js' import Status from '../status/status.vue' const sortAndFilterConversation = (conversation) => { - conversation = filter(conversation, (status) => statusType(status) !== 'retweet') + conversation = filter(conversation, (status) => status.type !== 'retweet') return sortBy(conversation, 'id') } @@ -18,10 +17,12 @@ const conversation = { 'collapsable' ], computed: { - status () { return this.statusoid }, + status () { + return this.statusoid + }, conversation () { if (!this.status) { - return false + return [] } const conversationId = this.status.statusnet_conversation_id diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index ff36a59b..48e5d480 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -44,6 +44,7 @@ const SUGGESTIONS_URL = '/api/v1/suggestions' const MASTODON_USER_FAVORITES_TIMELINE_URL = '/api/v1/favourites' import { each, map } from 'lodash' +import { parseStatus } from '../status_normalizer/status_normalizer.service.js' import 'whatwg-fetch' const oldfetch = window.fetch @@ -272,12 +273,14 @@ const fetchConversation = ({id, credentials}) => { let url = `${CONVERSATION_URL}/${id}.json?count=100` return fetch(url, { headers: authHeaders(credentials) }) .then((data) => data.json()) + .then((data) => data.map(parseStatus)) } const fetchStatus = ({id, credentials}) => { let url = `${STATUS_URL}/${id}.json` return fetch(url, { headers: authHeaders(credentials) }) .then((data) => data.json()) + .then((data) => parseStatus(data)) } const setUserMute = ({id, credentials, muted = true}) => { @@ -296,99 +299,6 @@ const setUserMute = ({id, credentials, muted = true}) => { }) } -export const statusType = (status) => { - if (status.is_post_verb) { - return 'status' - } - - if (status.retweeted_status) { - return 'retweet' - } - - if ((typeof status.uri === 'string' && status.uri.match(/(fave|objectType=Favourite)/)) || - (typeof status.text === 'string' && status.text.match(/favorited/))) { - return 'favorite' - } - - if (status.text.match(/deleted notice {{tag/) || status.qvitter_delete_notice) { - return 'deletion' - } - - if (status.text.match(/started following/) || status.activity_type === 'follow') { - return 'follow' - } - - return 'unknown' -} - -const isMastoAPI = (status) => { - return status.hasOwnProperty('account') -} - -const parseUser = (data) => { - return { - id: data.id, - screen_name: data.screen_name || data.acct - } -} - -const parseAttachment = (data) => { - return { - ...data, - mimetype: data.mimetype || data.type - } -} - -const parseData = (data) => { - const output = {} - const masto = isMastoAPI(data) - output.raw = data - output.id = data.id - - output.user = parseUser(masto ? data.account : data.user) - - output.attentions = ((masto ? data.mentions : data.attentions) || []).map(_ => ({ - id: _.id, - following: _.following // FIXME: MastoAPI doesn't have this - })) - - // FIXME: Masto doesn't have "raw text" data, using html data... - output.text = masto ? data.content : data.text - - output.attachments = ((masto ? data.media_attachments : data.attachments) || []).map(parseAttachment) - - const retweetedStatus = masto ? data.reblog : data.retweeted_status - if (retweetedStatus) { - output.retweeted_status = parseData(retweetedStatus) - } - - if (masto) { - output.type = data.reblog ? 'retweet' : 'status' - output.nsfw = data.sensitive - output.statusnet_html = data.content - } else { - // catchall, temporary - Object.assign(output, data) - - // QVitterAPI - output.type = statusType(data) - - if (data.nsfw === undefined) { - output.nsfw = isNsfw(data) - if (data.retweeted_status) { - output.nsfw = data.retweeted_status.nsfw - } - } - } - - return output -} - -const isNsfw = (status) => { - const nsfwRegex = /#nsfw/i - return (status.tags || []).includes('nsfw') || !!status.text.match(nsfwRegex) -} - const fetchTimeline = ({timeline, credentials, since = false, until = false, userId = false, tag = false}) => { const timelineUrls = { public: PUBLIC_TIMELINE_URL, @@ -401,10 +311,11 @@ const fetchTimeline = ({timeline, credentials, since = false, until = false, use favorites: MASTODON_USER_FAVORITES_TIMELINE_URL, tag: TAG_TIMELINE_URL } + const type = timeline.type || timeline + const isNotifications = type === 'notifications' + const params = [] - let url = timelineUrls[timeline.type || timeline] - - let params = [] + let url = timelineUrls[type] if (since) { params.push(['since_id', since]) @@ -432,7 +343,7 @@ const fetchTimeline = ({timeline, credentials, since = false, until = false, use throw new Error('Error fetching timeline') }) .then((data) => data.json()) - .then((data) => data.map(parseData)) + .then((data) => data.map(isNotifications ? _ => _ : parseStatus)) } const verifyCredentials = (user) => { diff --git a/src/services/status_normalizer/status_normalizer.service.js b/src/services/status_normalizer/status_normalizer.service.js new file mode 100644 index 00000000..ce7cd050 --- /dev/null +++ b/src/services/status_normalizer/status_normalizer.service.js @@ -0,0 +1,118 @@ +export const qvitterStatusType = (status) => { + if (status.is_post_verb) { + return 'status' + } + + if (status.retweeted_status) { + return 'retweet' + } + + if ((typeof status.uri === 'string' && status.uri.match(/(fave|objectType=Favourite)/)) || + (typeof status.text === 'string' && status.text.match(/favorited/))) { + return 'favorite' + } + + if (status.text.match(/deleted notice {{tag/) || status.qvitter_delete_notice) { + return 'deletion' + } + + if (status.text.match(/started following/) || status.activity_type === 'follow') { + return 'follow' + } + + return 'unknown' +} + +const isMastoAPI = (status) => { + return status.hasOwnProperty('account') +} + +const parseUser = (data) => { + return { + id: data.id, + screen_name: data.screen_name || data.acct + } +} + +const parseAttachment = (data) => { + return { + ...data, + mimetype: data.mimetype || data.type + } +} + +export const parseStatus = (data) => { + const output = {} + const masto = isMastoAPI(data) + output.raw = data + + console.log(masto ? 'MAMMAL' : 'OLD SHIT') + console.log(data) + if (masto) { + output.favorited = data.favourited + output.fave_num = data.favourites_count + + output.repeated = data.reblogged + output.repeat_num = data.reblogs_count + + output.type = data.reblog ? 'retweet' : 'status' + output.nsfw = data.sensitive + + output.statusnet_html = data.content + // Not exactly the same... + output.text = data.content + + output.in_reply_to_status_id = data.in_reply_to_id + output.in_reply_to_user_id = data.in_reply_to_user_id + } else { + output.favorited = data.favorited + output.fave_num = data.fave_num + + output.repeated = data.repeated + output.repeat_num = data.repeat_num + + // catchall, temporary + // Object.assign(output, data) + + output.type = qvitterStatusType(data) + + if (data.nsfw === undefined) { + output.nsfw = isNsfw(data) + if (data.retweeted_status) { + output.nsfw = data.retweeted_status.nsfw + } + } + output.statusnet_html = data.statusnet_html + output.text = data.text + + output.in_reply_to_status_id = data.in_reply_to_id + output.in_reply_to_user_id = data.in_reply_to_account_id + } + + output.id = Number(data.id) + output.visibility = data.visibility + output.created_at = new Date(data.created_at) + + output.user = parseUser(masto ? data.account : data.user) + + output.attentions = ((masto ? data.mentions : data.attentions) || []) + .map(_ => ({ + id: _.id, + following: _.following // FIXME: MastoAPI doesn't have this + })) + + output.attachments = ((masto ? data.media_attachments : data.attachments) || []) + .map(parseAttachment) + + const retweetedStatus = masto ? data.reblog : data.retweeted_status + if (retweetedStatus) { + output.retweeted_status = parseStatus(retweetedStatus) + } + + return output +} + +const isNsfw = (status) => { + const nsfwRegex = /#nsfw/i + return (status.tags || []).includes('nsfw') || !!status.text.match(nsfwRegex) +} -- cgit v1.2.3-70-g09d2 From 80a7035154ccd4ccf9f761d4117f286e352676e9 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Thu, 17 Jan 2019 23:08:44 +0300 Subject: removing unnecessary conversions since it should already be converted in normalizer --- src/components/conversation-page/conversation-page.js | 2 +- src/components/conversation/conversation.js | 7 ++++--- src/modules/statuses.js | 5 +---- src/modules/users.js | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-) (limited to 'src/components/conversation/conversation.js') diff --git a/src/components/conversation-page/conversation-page.js b/src/components/conversation-page/conversation-page.js index bdf84d0c..8f1ac3d9 100644 --- a/src/components/conversation-page/conversation-page.js +++ b/src/components/conversation-page/conversation-page.js @@ -7,7 +7,7 @@ const conversationPage = { }, computed: { statusoid () { - const id = String(this.$route.params.id) + const id = this.$route.params.id const statuses = this.$store.state.statuses.allStatuses const status = find(statuses, {id}) diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index 237de7e5..9bf5e136 100644 --- a/src/components/conversation/conversation.js +++ b/src/components/conversation/conversation.js @@ -33,7 +33,9 @@ const conversation = { replies () { let i = 1 return reduce(this.conversation, (result, {id, in_reply_to_status_id}) => { - const irid = String(in_reply_to_status_id) + /* eslint-disable camelcase */ + const irid = in_reply_to_status_id + /* eslint-enable camelcase */ if (irid) { result[irid] = result[irid] || [] result[irid].push({ @@ -70,7 +72,6 @@ const conversation = { } }, getReplies (id) { - id = String(id) return this.replies[id] || [] }, focused (id) { @@ -81,7 +82,7 @@ const conversation = { } }, setHighlight (id) { - this.highlight = String(id) + this.highlight = id } } } diff --git a/src/modules/statuses.js b/src/modules/statuses.js index f976fa42..83cf7256 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -64,9 +64,6 @@ const visibleNotificationTypes = (rootState) => { } const mergeOrAdd = (arr, obj, item) => { - // For sequential IDs BE passes numbers as numbers, we want them as strings. - item.id = String(item.id) - const oldItem = obj[item.id] if (oldItem) { @@ -164,7 +161,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us } const favoriteStatus = (favorite, counter) => { - const status = find(allStatuses, { id: String(favorite.in_reply_to_status_id) }) + const status = find(allStatuses, { id: favorite.in_reply_to_status_id }) if (status) { // This is our favorite, so the relevant bit. if (favorite.user.id === user.id) { diff --git a/src/modules/users.js b/src/modules/users.js index 0b55d701..d83f0dd8 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -151,7 +151,7 @@ const users = { }, addNewNotifications (store, { notifications }) { const users = map(notifications, 'from_profile') - const notificationIds = notifications.map(_ => String(_.id)) + const notificationIds = notifications.map(_ => _.id) store.commit('addNewUsers', users) const notificationsObject = store.rootState.statuses.notifications.idStore -- cgit v1.2.3-70-g09d2