File size: 2,505 Bytes
4d70170
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { computed, ref } from 'vue'
import type { Bridge } from '@vue-devtools/shared-utils'
import { BridgeEvents } from '@vue-devtools/shared-utils'
import { getBridge } from '@front/features/bridge'
import { useRoute, useRouter } from 'vue-router'
import { fetchLayers } from '../timeline/composable'

export interface AppRecord {
  id: string
  name: string
  version: string
  iframe: string
}

const apps = ref<AppRecord[]>([])

export function useCurrentApp() {
  const route = useRoute()
  const currentAppId = computed(() => route.params.appId as string)
  const currentApp = computed(() => apps.value.find(a => currentAppId.value === a.id))

  return {
    currentAppId,
    currentApp,
  }
}

export function useApps() {
  const router = useRouter()

  const {
    currentAppId,
    currentApp,
  } = useCurrentApp()

  function selectApp(id: string) {
    if (currentAppId.value !== id) {
      router.push({
        params: {
          appId: id.toString(),
          componentId: null,
        },
      })
    }
  }

  return {
    apps,
    currentAppId,
    currentApp,
    selectApp,
  }
}

function addApp(app: AppRecord) {
  removeApp(app.id)
  apps.value.push(app)
}

function removeApp(appId: string) {
  const index = apps.value.findIndex(app => app.id === appId)
  if (index !== -1) {
    apps.value.splice(index, 1)
  }
}

export function getApps() {
  return apps.value
}

function fetchApps() {
  getBridge().send(BridgeEvents.TO_BACK_APP_LIST, {})
}

export const pendingSelectAppId = ref<string | null>(null)

const pendingSelectPromises: (() => void)[] = []

export function waitForAppSelect(): Promise<void> {
  if (!pendingSelectAppId.value) {
    return Promise.resolve()
  }
  else {
    return new Promise((resolve) => {
      pendingSelectPromises.push(resolve)
    })
  }
}

export function scanLegacyApps() {
  getBridge().send(BridgeEvents.TO_BACK_SCAN_LEGACY_APPS, {})
}

export function setupAppsBridgeEvents(bridge: Bridge) {
  bridge.on(BridgeEvents.TO_FRONT_APP_ADD, ({ appRecord }) => {
    addApp(appRecord)
    fetchLayers()
  })

  bridge.on(BridgeEvents.TO_FRONT_APP_REMOVE, ({ id }) => {
    removeApp(id)
  })

  bridge.on(BridgeEvents.TO_FRONT_APP_LIST, ({ apps: list }) => {
    apps.value = list
  })

  bridge.on(BridgeEvents.TO_FRONT_APP_SELECTED, ({ id }) => {
    if (pendingSelectAppId.value === id) {
      pendingSelectAppId.value = null
      for (const resolve of pendingSelectPromises) {
        resolve()
      }
    }
  })

  fetchApps()
}