Merge branch 'better-still-emoji' into shigusegubu
* better-still-emoji: remove old emoji added, everything emoji-bearing uses RichContent now richcontent support in polls, user cards and user profiles support richcontent in polls
This commit is contained in:
commit
de30e0bf1a
16 changed files with 80 additions and 140 deletions
|
@ -1,5 +1,6 @@
|
||||||
import UserCard from '../user_card/user_card.vue'
|
import UserCard from '../user_card/user_card.vue'
|
||||||
import UserAvatar from '../user_avatar/user_avatar.vue'
|
import UserAvatar from '../user_avatar/user_avatar.vue'
|
||||||
|
import RichContent from 'src/components/rich_content/rich_content.jsx'
|
||||||
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
||||||
|
|
||||||
const BasicUserCard = {
|
const BasicUserCard = {
|
||||||
|
@ -13,7 +14,8 @@ const BasicUserCard = {
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
UserCard,
|
UserCard,
|
||||||
UserAvatar
|
UserAvatar,
|
||||||
|
RichContent
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleUserExpanded () {
|
toggleUserExpanded () {
|
||||||
|
|
|
@ -25,17 +25,11 @@
|
||||||
:title="user.name"
|
:title="user.name"
|
||||||
class="basic-user-card-user-name"
|
class="basic-user-card-user-name"
|
||||||
>
|
>
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
<RichContent
|
||||||
<span
|
|
||||||
v-if="user.name_html"
|
|
||||||
class="basic-user-card-user-name-value"
|
class="basic-user-card-user-name-value"
|
||||||
v-html="user.name_html"
|
:html="user.name"
|
||||||
|
:emoji="user.emoji"
|
||||||
/>
|
/>
|
||||||
<!-- eslint-enable vue/no-v-html -->
|
|
||||||
<span
|
|
||||||
v-else
|
|
||||||
class="basic-user-card-user-name-value"
|
|
||||||
>{{ user.name }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<router-link
|
<router-link
|
||||||
|
|
|
@ -4,6 +4,7 @@ import Status from '../status/status.vue'
|
||||||
import UserAvatar from '../user_avatar/user_avatar.vue'
|
import UserAvatar from '../user_avatar/user_avatar.vue'
|
||||||
import UserCard from '../user_card/user_card.vue'
|
import UserCard from '../user_card/user_card.vue'
|
||||||
import Timeago from '../timeago/timeago.vue'
|
import Timeago from '../timeago/timeago.vue'
|
||||||
|
import RichContent from 'src/components/rich_content/rich_content.jsx'
|
||||||
import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
|
import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
|
||||||
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
|
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
|
||||||
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
||||||
|
@ -44,7 +45,8 @@ const Notification = {
|
||||||
UserAvatar,
|
UserAvatar,
|
||||||
UserCard,
|
UserCard,
|
||||||
Timeago,
|
Timeago,
|
||||||
Status
|
Status,
|
||||||
|
RichContent
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleUserExpanded () {
|
toggleUserExpanded () {
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
|
|
||||||
|
--emoji-size: 14px;
|
||||||
|
|
||||||
&.-muted {
|
&.-muted {
|
||||||
padding: 0.25em 0.6em;
|
padding: 0.25em 0.6em;
|
||||||
height: 1.2em;
|
height: 1.2em;
|
||||||
|
|
|
@ -52,12 +52,14 @@
|
||||||
<span class="notification-details">
|
<span class="notification-details">
|
||||||
<div class="name-and-action">
|
<div class="name-and-action">
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
<!-- eslint-disable vue/no-v-html -->
|
||||||
<bdi
|
<bdi v-if="!!notification.from_profile.name_html">
|
||||||
v-if="!!notification.from_profile.name_html"
|
<RichContent
|
||||||
class="username"
|
class="username"
|
||||||
:title="'@'+notification.from_profile.screen_name_ui"
|
:title="'@'+notification.from_profile.screen_name_ui"
|
||||||
v-html="notification.from_profile.name_html"
|
:html="notification.from_profile.name_html"
|
||||||
|
:emoji="notification.from_profile.emoji"
|
||||||
/>
|
/>
|
||||||
|
</bdi>
|
||||||
<!-- eslint-enable vue/no-v-html -->
|
<!-- eslint-enable vue/no-v-html -->
|
||||||
<span
|
<span
|
||||||
v-else
|
v-else
|
||||||
|
|
|
@ -143,13 +143,6 @@
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
img {
|
|
||||||
width: 14px;
|
|
||||||
height: 14px;
|
|
||||||
vertical-align: middle;
|
|
||||||
object-fit: contain
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeago {
|
.timeago {
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
import Timeago from '../timeago/timeago.vue'
|
import Timeago from 'components/timeago/timeago.vue'
|
||||||
|
import RichContent from 'components/rich_content/rich_content.jsx'
|
||||||
import { forEach, map } from 'lodash'
|
import { forEach, map } from 'lodash'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Poll',
|
name: 'Poll',
|
||||||
props: ['basePoll'],
|
props: ['basePoll', 'emoji'],
|
||||||
components: { Timeago },
|
components: {
|
||||||
|
Timeago,
|
||||||
|
RichContent
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
loading: false,
|
loading: false,
|
||||||
|
|
|
@ -17,8 +17,11 @@
|
||||||
<span class="result-percentage">
|
<span class="result-percentage">
|
||||||
{{ percentageForOption(option.votes_count) }}%
|
{{ percentageForOption(option.votes_count) }}%
|
||||||
</span>
|
</span>
|
||||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
<RichContent
|
||||||
<span v-html="option.title_html" />
|
:html="option.title_html"
|
||||||
|
:handle-links="false"
|
||||||
|
:emoji="emoji"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="result-fill"
|
class="result-fill"
|
||||||
|
@ -42,8 +45,11 @@
|
||||||
:value="index"
|
:value="index"
|
||||||
>
|
>
|
||||||
<label class="option-vote">
|
<label class="option-vote">
|
||||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
<RichContent
|
||||||
<div v-html="option.title_html" />
|
:html="option.title_html"
|
||||||
|
:handle-links="false"
|
||||||
|
:emoji="emoji"
|
||||||
|
/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.emoji {
|
.emoji {
|
||||||
|
display: inline-block;
|
||||||
width: var(--emoji-size, 32px);
|
width: var(--emoji-size, 32px);
|
||||||
height: var(--emoji-size, 32px);
|
height: var(--emoji-size, 32px);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,10 @@
|
||||||
@parseReady="$emit('parseReady', $event)"
|
@parseReady="$emit('parseReady', $event)"
|
||||||
>
|
>
|
||||||
<div v-if="status.poll && status.poll.options">
|
<div v-if="status.poll && status.poll.options">
|
||||||
<poll :base-poll="status.poll" />
|
<Poll
|
||||||
|
:base-poll="status.poll"
|
||||||
|
:emoji="status.emojis"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<gallery
|
<gallery
|
||||||
|
|
|
@ -5,6 +5,7 @@ import FollowButton from '../follow_button/follow_button.vue'
|
||||||
import ModerationTools from '../moderation_tools/moderation_tools.vue'
|
import ModerationTools from '../moderation_tools/moderation_tools.vue'
|
||||||
import AccountActions from '../account_actions/account_actions.vue'
|
import AccountActions from '../account_actions/account_actions.vue'
|
||||||
import Select from '../select/select.vue'
|
import Select from '../select/select.vue'
|
||||||
|
import RichContent from 'src/components/rich_content/rich_content.jsx'
|
||||||
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
@ -118,7 +119,8 @@ export default {
|
||||||
AccountActions,
|
AccountActions,
|
||||||
ProgressButton,
|
ProgressButton,
|
||||||
FollowButton,
|
FollowButton,
|
||||||
Select
|
Select,
|
||||||
|
RichContent
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
muteUser () {
|
muteUser () {
|
||||||
|
|
|
@ -38,21 +38,12 @@
|
||||||
</router-link>
|
</router-link>
|
||||||
<div class="user-summary">
|
<div class="user-summary">
|
||||||
<div class="top-line">
|
<div class="top-line">
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
<RichContent
|
||||||
<div
|
|
||||||
v-if="user.name_html"
|
|
||||||
:title="user.name"
|
:title="user.name"
|
||||||
class="user-name"
|
class="user-name"
|
||||||
v-html="user.name_html"
|
:html="user.name"
|
||||||
|
:emoji="user.emoji"
|
||||||
/>
|
/>
|
||||||
<!-- eslint-enable vue/no-v-html -->
|
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
:title="user.name"
|
|
||||||
class="user-name"
|
|
||||||
>
|
|
||||||
{{ user.name }}
|
|
||||||
</div>
|
|
||||||
<button
|
<button
|
||||||
v-if="isOtherUser && !user.is_local"
|
v-if="isOtherUser && !user.is_local"
|
||||||
:href="user.statusnet_profile_url"
|
:href="user.statusnet_profile_url"
|
||||||
|
@ -255,20 +246,12 @@
|
||||||
<span>{{ hideFollowersCount ? $t('user_card.hidden') : user.followers_count }}</span>
|
<span>{{ hideFollowersCount ? $t('user_card.hidden') : user.followers_count }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
<RichContent
|
||||||
<p
|
v-if="!hideBio"
|
||||||
v-if="!hideBio && user.description_html"
|
|
||||||
class="user-card-bio"
|
class="user-card-bio"
|
||||||
@click.prevent="linkClicked"
|
:html="user.description_html"
|
||||||
v-html="user.description_html"
|
:emoji="user.emoji"
|
||||||
/>
|
/>
|
||||||
<!-- eslint-enable vue/no-v-html -->
|
|
||||||
<p
|
|
||||||
v-else-if="!hideBio"
|
|
||||||
class="user-card-bio"
|
|
||||||
>
|
|
||||||
{{ user.description }}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -281,9 +264,10 @@
|
||||||
.user-card {
|
.user-card {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&:hover .Avatar {
|
&:hover {
|
||||||
--_still-image-img-visibility: visible;
|
--_still-image-img-visibility: visible;
|
||||||
--_still-image-canvas-visibility: hidden;
|
--_still-image-canvas-visibility: hidden;
|
||||||
|
--_still-image-label-visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-heading {
|
.panel-heading {
|
||||||
|
@ -327,12 +311,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-bio {
|
&-bio {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
display: block;
|
||||||
|
line-height: 18px;
|
||||||
|
padding: 1em;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: $fallback--link;
|
color: $fallback--link;
|
||||||
|
@ -344,11 +328,6 @@
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 400px;
|
max-height: 400px;
|
||||||
|
|
||||||
&.emoji {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,13 +429,6 @@
|
||||||
// big one
|
// big one
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
||||||
img {
|
|
||||||
width: 26px;
|
|
||||||
height: 26px;
|
|
||||||
vertical-align: middle;
|
|
||||||
object-fit: contain
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-line {
|
.top-line {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
@ -469,12 +441,7 @@
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
|
||||||
img {
|
--emoji-size: 14px;
|
||||||
object-fit: contain;
|
|
||||||
height: 16px;
|
|
||||||
width: 16px;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bottom-line {
|
.bottom-line {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import FollowCard from '../follow_card/follow_card.vue'
|
||||||
import Timeline from '../timeline/timeline.vue'
|
import Timeline from '../timeline/timeline.vue'
|
||||||
import Conversation from '../conversation/conversation.vue'
|
import Conversation from '../conversation/conversation.vue'
|
||||||
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.js'
|
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.js'
|
||||||
|
import RichContent from 'src/components/rich_content/rich_content.jsx'
|
||||||
import List from '../list/list.vue'
|
import List from '../list/list.vue'
|
||||||
import withLoadMore from '../../hocs/with_load_more/with_load_more'
|
import withLoadMore from '../../hocs/with_load_more/with_load_more'
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||||
|
@ -164,7 +165,8 @@ const UserProfile = {
|
||||||
FriendList,
|
FriendList,
|
||||||
FollowCard,
|
FollowCard,
|
||||||
TabSwitcher,
|
TabSwitcher,
|
||||||
Conversation
|
Conversation,
|
||||||
|
RichContent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,20 +20,24 @@
|
||||||
:key="index"
|
:key="index"
|
||||||
class="user-profile-field"
|
class="user-profile-field"
|
||||||
>
|
>
|
||||||
<!-- eslint-disable vue/no-v-html -->
|
|
||||||
<dt
|
<dt
|
||||||
:title="user.fields_text[index].name"
|
:title="user.fields_text[index].name"
|
||||||
class="user-profile-field-name"
|
class="user-profile-field-name"
|
||||||
@click.prevent="linkClicked"
|
>
|
||||||
v-html="field.name"
|
<RichContent
|
||||||
|
:html="field.name"
|
||||||
|
:emoji="user.emoji"
|
||||||
/>
|
/>
|
||||||
|
</dt>
|
||||||
<dd
|
<dd
|
||||||
:title="user.fields_text[index].value"
|
:title="user.fields_text[index].value"
|
||||||
class="user-profile-field-value"
|
class="user-profile-field-value"
|
||||||
@click.prevent="linkClicked"
|
>
|
||||||
v-html="field.value"
|
<RichContent
|
||||||
|
:html="field.value"
|
||||||
|
:emoji="user.emoji"
|
||||||
/>
|
/>
|
||||||
<!-- eslint-enable vue/no-v-html -->
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
<tab-switcher
|
<tab-switcher
|
||||||
|
|
|
@ -56,16 +56,17 @@ export const parseUser = (data) => {
|
||||||
|
|
||||||
output.emoji = data.emojis
|
output.emoji = data.emojis
|
||||||
output.name = data.display_name
|
output.name = data.display_name
|
||||||
output.name_html = addEmojis(escape(data.display_name), data.emojis)
|
output.name_html = escape(data.display_name)
|
||||||
|
|
||||||
output.description = data.note
|
output.description = data.note
|
||||||
output.description_html = addEmojis(data.note, data.emojis)
|
// TODO cleanup this shit, output.description is overriden with source data
|
||||||
|
output.description_html = data.note
|
||||||
|
|
||||||
output.fields = data.fields
|
output.fields = data.fields
|
||||||
output.fields_html = data.fields.map(field => {
|
output.fields_html = data.fields.map(field => {
|
||||||
return {
|
return {
|
||||||
name: addEmojis(escape(field.name), data.emojis),
|
name: escape(field.name),
|
||||||
value: addEmojis(field.value, data.emojis)
|
value: field.value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
output.fields_text = data.fields.map(field => {
|
output.fields_text = data.fields.map(field => {
|
||||||
|
@ -240,16 +241,6 @@ export const parseAttachment = (data) => {
|
||||||
|
|
||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
export const addEmojis = (string, emojis) => {
|
|
||||||
const matchOperatorsRegex = /[|\\{}()[\]^$+*?.-]/g
|
|
||||||
return emojis.reduce((acc, emoji) => {
|
|
||||||
const regexSafeShortCode = emoji.shortcode.replace(matchOperatorsRegex, '\\$&')
|
|
||||||
return acc.replace(
|
|
||||||
new RegExp(`:${regexSafeShortCode}:`, 'g'),
|
|
||||||
`<img src='${emoji.url}' alt=':${emoji.shortcode}:' title=':${emoji.shortcode}:' class='emoji' />`
|
|
||||||
)
|
|
||||||
}, string)
|
|
||||||
}
|
|
||||||
|
|
||||||
export const parseStatus = (data) => {
|
export const parseStatus = (data) => {
|
||||||
const output = {}
|
const output = {}
|
||||||
|
@ -301,7 +292,7 @@ export const parseStatus = (data) => {
|
||||||
if (output.poll) {
|
if (output.poll) {
|
||||||
output.poll.options = (output.poll.options || []).map(field => ({
|
output.poll.options = (output.poll.options || []).map(field => ({
|
||||||
...field,
|
...field,
|
||||||
title_html: addEmojis(escape(field.title), data.emojis)
|
title_html: escape(field.title)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
output.pinned = data.pinned
|
output.pinned = data.pinned
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { parseStatus, parseUser, parseNotification, addEmojis, parseLinkHeaderPagination } from '../../../../../src/services/entity_normalizer/entity_normalizer.service.js'
|
import { parseStatus, parseUser, parseNotification, parseLinkHeaderPagination } from '../../../../../src/services/entity_normalizer/entity_normalizer.service.js'
|
||||||
import mastoapidata from '../../../../fixtures/mastoapi.json'
|
import mastoapidata from '../../../../fixtures/mastoapi.json'
|
||||||
import qvitterapidata from '../../../../fixtures/statuses.json'
|
import qvitterapidata from '../../../../fixtures/statuses.json'
|
||||||
|
|
||||||
|
@ -338,41 +338,6 @@ describe('API Entities normalizer', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('MastoAPI emoji adder', () => {
|
|
||||||
const emojis = makeMockEmojiMasto()
|
|
||||||
const imageHtml = '<img src="https://example.com/image.png" alt=":image:" title=":image:" class="emoji" />'
|
|
||||||
.replace(/"/g, '\'')
|
|
||||||
const thinkHtml = '<img src="https://example.com/think.png" alt=":thinking:" title=":thinking:" class="emoji" />'
|
|
||||||
.replace(/"/g, '\'')
|
|
||||||
|
|
||||||
it('correctly replaces shortcodes in supplied string', () => {
|
|
||||||
const result = addEmojis('This post has :image: emoji and :thinking: emoji', emojis)
|
|
||||||
expect(result).to.include(thinkHtml)
|
|
||||||
expect(result).to.include(imageHtml)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('handles consecutive emojis correctly', () => {
|
|
||||||
const result = addEmojis('Lelel emoji spam :thinking::thinking::thinking::thinking:', emojis)
|
|
||||||
expect(result).to.include(thinkHtml + thinkHtml + thinkHtml + thinkHtml)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Doesn\'t replace nonexistent emojis', () => {
|
|
||||||
const result = addEmojis('Admin add the :tenshi: emoji', emojis)
|
|
||||||
expect(result).to.equal('Admin add the :tenshi: emoji')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('Doesn\'t blow up on regex special characters', () => {
|
|
||||||
const emojis = makeMockEmojiMasto([{
|
|
||||||
shortcode: 'c++'
|
|
||||||
}, {
|
|
||||||
shortcode: '[a-z] {|}*'
|
|
||||||
}])
|
|
||||||
const result = addEmojis('This post has :c++: emoji and :[a-z] {|}*: emoji', emojis)
|
|
||||||
expect(result).to.include('title=\':c++:\'')
|
|
||||||
expect(result).to.include('title=\':[a-z] {|}*:\'')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('Link header pagination', () => {
|
describe('Link header pagination', () => {
|
||||||
it('Parses min and max ids as integers', () => {
|
it('Parses min and max ids as integers', () => {
|
||||||
const linkHeader = '<https://example.com/api/v1/notifications?max_id=861676>; rel="next", <https://example.com/api/v1/notifications?min_id=861741>; rel="prev"'
|
const linkHeader = '<https://example.com/api/v1/notifications?max_id=861676>; rel="next", <https://example.com/api/v1/notifications?min_id=861741>; rel="prev"'
|
||||||
|
|
Loading…
Add table
Reference in a new issue