[ABANDONED] React/Redux front end for the Flexor social network.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

283 lines
8.4 KiB

// 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
}
}