|
|
// apps.ts
// Copyright (C) 2020 Dwayne Harris
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import { apiFetch } from '../api' import { setEntities } from '../actions/entities' import { startRequest, finishRequest } from '../actions/requests' import { setFieldNotification } from '../actions/forms' import { listSet, listAppend } from '../actions/lists' import { objectToQuerystring } from '../utils' import { normalize } from '../utils/normalization' import { EntityListKey, Entity } from '../types'
import { AppThunkAction, RequestKey, EntityType, App, AvailabilityResponse, NotificationType }from '../types'
interface AppsResponse { apps: App[] continuation?: string }
export const fetchApps = (sort?: string, continuation?: string): AppThunkAction => async dispatch => { dispatch(startRequest(RequestKey.FetchApps))
try { const response = await apiFetch<AppsResponse>({ path: `/v1/apps?${objectToQuerystring({ sort, continuation })}`, })
const apps = normalize(response.apps, EntityType.App)
dispatch(setEntities(apps.entities)) if (continuation) { dispatch(listAppend(EntityListKey.Apps, apps.keys, response.continuation)) } else { dispatch(listSet(EntityListKey.Apps, apps.keys, response.continuation)) }
dispatch(finishRequest(RequestKey.FetchApps, true)) } catch (err) { dispatch(finishRequest(RequestKey.FetchApps, false)) throw err } }
export const fetchCreatedApps = (sort?: string): AppThunkAction => async dispatch => { dispatch(startRequest(RequestKey.FetchSelfApps))
try { const response = await apiFetch<AppsResponse>({ path: `/v1/self/apps?${objectToQuerystring({ sort })}`, })
const apps = normalize(response.apps, EntityType.App)
dispatch(setEntities(apps.entities)) dispatch(listSet(EntityListKey.CreatedApps, apps.keys)) dispatch(finishRequest(RequestKey.FetchSelfApps, true)) } catch (err) { dispatch(finishRequest(RequestKey.FetchSelfApps, false)) throw err } }
export const checkAppAvailability = (name: string): AppThunkAction => async dispatch => { dispatch(startRequest(RequestKey.FetchAppAvailability))
try { const { id, available } = await apiFetch<AvailabilityResponse>({ path: '/v1/app/available', method: 'post', body: { name, }, })
if (available) { dispatch(setFieldNotification('name', NotificationType.Success, `${id} is available`)) } else { dispatch(setFieldNotification('name', NotificationType.Error, `${id} isn't available`)) }
dispatch(finishRequest(RequestKey.FetchAppAvailability, true)) } catch (err) { dispatch(finishRequest(RequestKey.FetchAppAvailability, false)) throw err } }
interface AppOptions { name: string about?: string websiteUrl?: string companyName?: string version: string composerUrl?: string rendererUrl?: string imageUrl?: string coverImageUrl?: string iconImageUrl?: string }
interface CreateAppResponse { id: string }
export const createApp = (options: AppOptions): AppThunkAction<string> => async dispatch => { const { name, about, websiteUrl, companyName, version, composerUrl, rendererUrl, imageUrl, coverImageUrl, iconImageUrl } = options dispatch(startRequest(RequestKey.CreateApp))
try { const { id } = await apiFetch<CreateAppResponse>({ path: '/v1/app', method: 'post', body: { name, about, websiteUrl, companyName, version, composerUrl, rendererUrl, imageUrl, coverImageUrl, iconImageUrl, }, })
dispatch(finishRequest(RequestKey.CreateApp, true)) return id } catch (err) { dispatch(finishRequest(RequestKey.CreateApp, false)) throw err } }
export const updateApp = (id: string, options: AppOptions): AppThunkAction => async dispatch => { const { name, about, websiteUrl, companyName, version, composerUrl, rendererUrl, imageUrl, coverImageUrl, iconImageUrl } = options dispatch(startRequest(RequestKey.UpdateApp))
try { await apiFetch({ path: `/v1/app/${id}`, method: 'put', body: { name, about, websiteUrl, companyName, version, composerUrl, rendererUrl, imageUrl, coverImageUrl, iconImageUrl, }, })
dispatch(finishRequest(RequestKey.UpdateApp, true)) } catch (err) { dispatch(finishRequest(RequestKey.UpdateApp, false)) throw err } }
export const fetchApp = (id: string): AppThunkAction => async dispatch => { dispatch(startRequest(RequestKey.FetchApp))
try { const app = await apiFetch<App>({ path: `/v1/app/${id}`, method: 'get', })
const apps = normalize([app], EntityType.App) dispatch(setEntities(apps.entities)) dispatch(finishRequest(RequestKey.FetchApp, true)) } catch (err) { dispatch(finishRequest(RequestKey.FetchApp, false)) throw err } }
export const installApp = (id: string): AppThunkAction => async dispatch => { dispatch(startRequest(RequestKey.InstallApp))
try { await apiFetch({ path: `/v1/app/${id}/install`, method: 'post' })
dispatch(finishRequest(RequestKey.InstallApp, true)) } catch (err) { dispatch(finishRequest(RequestKey.InstallApp, false)) throw err } }
export const uninstallApp = (id: string): AppThunkAction => async dispatch => { dispatch(startRequest(RequestKey.UninstallApp))
try { await apiFetch({ path: `/v1/app/${id}/uninstall`, method: 'post' })
dispatch(finishRequest(RequestKey.UninstallApp, true)) } catch (err) { dispatch(finishRequest(RequestKey.UninstallApp, false)) throw err } }
interface FetchPendingAppsResponse { apps: Entity[] continuation?: string }
export const fetchPendingApps = (continuation?: string): AppThunkAction => async dispatch => { dispatch(startRequest(RequestKey.FetchPendingApps))
try { const response = await apiFetch<FetchPendingAppsResponse>({ path: `/v1/apps/pending?${objectToQuerystring({ continuation })}`, method: 'get', })
const apps = normalize(response.apps, EntityType.App)
dispatch(setEntities(apps.entities)) dispatch(listSet(EntityListKey.PendingApps, apps.keys, response.continuation)) dispatch(finishRequest(RequestKey.FetchPendingApps, true)) } catch (err) { dispatch(finishRequest(RequestKey.FetchPendingApps, false)) throw err } }
export const activateApp = (id: string): AppThunkAction => async dispatch => { dispatch(startRequest(RequestKey.ActivateApp))
try { await apiFetch({ path: `/v1/app/${id}/activate`, method: 'post', })
dispatch(finishRequest(RequestKey.ActivateApp, true)) } catch (err) { dispatch(finishRequest(RequestKey.ActivateApp, false)) throw err } }
export const setPreinstall = (id: string): AppThunkAction => async dispatch => { dispatch(startRequest(RequestKey.SetPreinstall))
try { await apiFetch({ path: `/v1/app/${id}/preinstall`, method: 'post', })
dispatch(finishRequest(RequestKey.SetPreinstall, true)) } catch (err) { dispatch(finishRequest(RequestKey.SetPreinstall, false)) throw err } }
|