ENH - open exact EasyShare content targets

This commit is contained in:
smx.pusha
2026-08-12 07:44:55 +02:00
parent eeb3396f52
commit ea34dce1c8
13 changed files with 169 additions and 4 deletions
+8
View File
@@ -183,4 +183,12 @@ describe('FlipTok verification updates', () => {
expect(store.feed).toEqual([])
expect(store.activities).toEqual([])
})
it('loads an exact shared video by id', async () => {
vi.mocked(nuiCall).mockResolvedValue({ success: true, data: { ...video } })
const store = useFlipTokStore()
expect(await store.loadVideo(video.id)).toEqual(video)
expect(nuiCall).toHaveBeenCalledWith('fliptok:video', { id: video.id })
})
})
+4
View File
@@ -114,6 +114,10 @@ export const useFlipTokStore = defineStore('fliptok', {
this.feed = response.data.items
return true
},
async loadVideo(id: string): Promise<FlipTokVideo | null> {
const response = await nuiCall<FlipTokVideo>('fliptok:video', { id })
return response.success && response.data ? response.data : null
},
async discover(search: string): Promise<FlipTokVideo[]> {
const response = await nuiCall<FlipTokVideo[]>('fliptok:discover', {
search,
+8
View File
@@ -213,4 +213,12 @@ describe('Picstagram store', () => {
expect(store.feed).toEqual([])
expect(store.stories).toEqual([])
})
it('loads an exact shared post by id', async () => {
vi.mocked(nuiCall).mockResolvedValue({ success: true, data: { ...post } })
const store = usePicstagramStore()
expect(await store.loadPost(post.id)).toEqual(post)
expect(nuiCall).toHaveBeenCalledWith('picstagram:post', { id: post.id })
})
})
+4
View File
@@ -127,6 +127,10 @@ export const usePicstagramStore = defineStore('picstagram', {
this.feedCursor = response.data.nextCursor
return true
},
async loadPost(id: string): Promise<PicstagramPost | null> {
const response = await nuiCall<PicstagramPost>('picstagram:post', { id })
return response.success && response.data ? response.data : null
},
async loadExplore(append = false): Promise<boolean> {
const response = await nuiCall<PicstagramPage>('picstagram:explore', {
cursor: append ? this.exploreCursor : undefined,
+22
View File
@@ -49,4 +49,26 @@ describe('EasyShare deep links', () => {
).query.listingId,
).toBe('listing-1')
})
it.each([
['picstagram', 'post', 'pic-post-1', '/apps/picstagram'],
['picstagram', 'profile', 'pic-profile-1', '/apps/picstagram'],
['feather', 'post', 'feather-post-1', '/apps/feather'],
['fliptok', 'post', 'fliptok-1', '/apps/fliptok'],
['local-pages', 'post', 'pages-post-1', '/apps/local-pages'],
])('preserves the exact %s %s target', (appId, kind, id, path) => {
expect(
easyShareRoute(
payload({
appId: appId as EasySharePayload['appId'],
id,
kind: kind as EasySharePayload['kind'],
link: `skyphone://${appId}/${kind}/${id}`,
}),
),
).toMatchObject({
path,
query: { easyShareId: id, easyShareKind: kind },
})
})
})
+11
View File
@@ -709,6 +709,17 @@ onMounted(async () => {
if (route.query.compose === '1') screen.value = 'composer'
await feather.bootstrap()
if (feather.onboarded) {
const easyShareId = String(route.query.easyShareId ?? '')
if (easyShareId && route.query.easyShareKind === 'profile') {
const profileId = Number(easyShareId)
if (Number.isInteger(profileId) && profileId > 0)
await openProfile(profileId)
} else if (easyShareId && route.query.easyShareKind === 'post') {
if (await feather.loadThread(easyShareId)) {
threadReplyTarget.value = feather.thread?.post ?? null
screen.value = 'thread'
}
}
await feather.loadActivities()
if (tab.value === 'profile' && feather.profile)
await feather.loadProfile(feather.profile.id)
+14 -1
View File
@@ -50,7 +50,7 @@ import {
kToggle,
} from 'konsta/vue'
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import flipTokIcon from '@/assets/img/app-icons/fliptok.webp'
import { useFlipTokStore } from '@/stores/fliptok'
@@ -71,6 +71,7 @@ type AuthMode = 'login' | 'register'
const phone = usePhoneStore()
const store = useFlipTokStore()
const messageMedia = useMessageMediaStore()
const route = useRoute()
const router = useRouter()
const authMode = ref<AuthMode>('login')
const authHandle = ref('')
@@ -776,6 +777,18 @@ onMounted(async () => {
composeOpen.value = true
}
await store.bootstrap()
const easyShareId = String(route.query.easyShareId ?? '')
if (easyShareId && route.query.easyShareKind === 'profile') {
const profileId = Number(easyShareId)
if (Number.isInteger(profileId) && profileId > 0)
await openProfile(profileId)
} else if (easyShareId && route.query.easyShareKind === 'post') {
const video = await store.loadVideo(easyShareId)
if (video) {
store.feed = [video]
tab.value = 'feed'
}
}
await nextTick()
observeVideos()
})
+11 -2
View File
@@ -279,7 +279,7 @@ function sharePost(): void {
})
}
onMounted(() => {
onMounted(async () => {
const selection = messageMedia.consumeMany<MediaContext>('local-pages:compose')
if (selection) {
if (selection.context) {
@@ -294,7 +294,16 @@ onMounted(() => {
}
}
if (route.query.compose === '1') screen.value = 'compose'
void loadFeed()
await loadFeed()
const easyShareId = String(route.query.easyShareId ?? '')
if (easyShareId && route.query.easyShareKind === 'post') {
const response = await pages.get(easyShareId)
if (response.success && response.data) {
selected.value = response.data
galleryIndex.value = 0
screen.value = 'detail'
}
}
})
</script>
+12 -1
View File
@@ -55,7 +55,7 @@ import {
kToggle,
} from 'konsta/vue'
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import picstagramIcon from '@/assets/img/app-icons/picstagram.webp'
import { useMessageMediaStore } from '@/stores/messageMedia'
@@ -80,6 +80,7 @@ type ProfileSection = 'photos' | 'saved'
const phone = usePhoneStore()
const store = usePicstagramStore()
const mediaPicker = useMessageMediaStore()
const route = useRoute()
const router = useRouter()
const tab = ref<Tab>('home')
@@ -629,6 +630,16 @@ watch(profileSection, (section) => {
onMounted(async () => {
await store.bootstrap()
const easyShareId = String(route.query.easyShareId ?? '')
if (easyShareId && route.query.easyShareKind === 'profile') {
await openProfile(easyShareId)
} else if (easyShareId && route.query.easyShareKind === 'post') {
const post = await store.loadPost(easyShareId)
if (post) {
tab.value = 'home'
selectedPost.value = post
}
}
const composeSelection = mediaPicker.consumeMany<{
caption?: string
commentsEnabled?: boolean
+18
View File
@@ -5387,6 +5387,15 @@ app.post('/api/:endpoint', (request, response) => {
})
return
}
if (endpoint === 'picstagram:post') {
const post = picstagramPosts.find((item) => item.id === request.body.id)
response.json(
post
? { success: true, data: post }
: { success: false, error: 'post_not_found' },
)
return
}
if (endpoint === 'picstagram:explore') {
response.json({
success: true,
@@ -5768,6 +5777,15 @@ app.post('/api/:endpoint', (request, response) => {
response.json({ success: true })
return
}
if (endpoint === 'fliptok:video') {
const video = flipTokVideos.find((item) => item.id === request.body.id)
response.json(
video
? { success: true, data: video }
: { success: false, error: 'video_not_found' },
)
return
}
if (endpoint === 'fliptok:follow') {
flipTokVideos
.filter((video) => video.profile_id === request.body.profileId)