From ba0f5e5b3072b5d7c904a3105e4e7c5bdd83316f Mon Sep 17 00:00:00 2001 From: Janne Mareike Koschinski <janne@kuschku.de> Date: Sat, 31 Jul 2021 01:41:52 +0200 Subject: [PATCH] Further improve image APIs --- api/album_get.go | 13 ++++++++++++ api/album_list.go | 16 +++++++++++++++ api/albumimage_get.go | 25 ----------------------- api/albumimage_list.go | 25 ----------------------- cmd/frontend/main.go | 6 ------ model/album.go | 13 ++++++------ model/album_image.go | 11 ++++++++++ ui/src/App.tsx | 2 +- ui/src/ImageList.tsx | 30 ---------------------------- ui/src/api/model/Album.ts | 3 +++ ui/src/api/model/AlbumImage.ts | 1 + ui/src/api/useGetAlbum.ts | 20 +++++++++++++++++++ ui/src/api/useGetImage.ts | 20 +++++++++++++++++++ ui/src/api/useListAlbums.ts | 20 +++++++++++++++++++ ui/src/api/useListImages.ts | 2 +- ui/src/components/AlbumImageView.tsx | 17 ++++++++++++++++ ui/src/components/AlbumList.tsx | 22 ++++++++++++++++++++ ui/src/components/AlbumView.tsx | 28 ++++++++++++++++++++++++++ ui/src/components/ImageList.tsx | 22 ++++++++++++++++++++ ui/src/components/ImageView.tsx | 23 +++++++++++++++++++++ 20 files changed, 225 insertions(+), 94 deletions(-) delete mode 100644 api/albumimage_get.go delete mode 100644 api/albumimage_list.go delete mode 100644 ui/src/ImageList.tsx create mode 100644 ui/src/api/useGetAlbum.ts create mode 100644 ui/src/api/useGetImage.ts create mode 100644 ui/src/api/useListAlbums.ts create mode 100644 ui/src/components/AlbumImageView.tsx create mode 100644 ui/src/components/AlbumList.tsx create mode 100644 ui/src/components/AlbumView.tsx create mode 100644 ui/src/components/ImageList.tsx create mode 100644 ui/src/components/ImageView.tsx diff --git a/api/album_get.go b/api/album_get.go index 063b8e0..928b2b4 100644 --- a/api/album_get.go +++ b/api/album_get.go @@ -19,6 +19,19 @@ func GetAlbum(env environment.FrontendEnvironment) http.Handler { http.Error(writer, err.Error(), http.StatusInternalServerError) return } + album.Images, err = env.Repositories.AlbumImages.List(album.Id) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } + for i, image := range album.Images { + err = image.LoadUrl(env.Storage, env.Configuration.Storage) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } + album.Images[i] = image + } util.ReturnJson(writer, album) }) diff --git a/api/album_list.go b/api/album_list.go index c29898b..74d0f4e 100644 --- a/api/album_list.go +++ b/api/album_list.go @@ -22,6 +22,22 @@ func ListAlbums(env environment.FrontendEnvironment) http.Handler { http.Error(writer, err.Error(), http.StatusInternalServerError) return } + for i, album := range albums { + album.Images, err = env.Repositories.AlbumImages.List(album.Id) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } + for j, image := range album.Images { + err = image.LoadUrl(env.Storage, env.Configuration.Storage) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return + } + album.Images[j] = image + } + albums[i] = album + } util.ReturnJson(writer, albums) }) diff --git a/api/albumimage_get.go b/api/albumimage_get.go deleted file mode 100644 index f85a592..0000000 --- a/api/albumimage_get.go +++ /dev/null @@ -1,25 +0,0 @@ -package api - -import ( - "database/sql" - "git.kuschku.de/justjanne/imghost-frontend/environment" - "git.kuschku.de/justjanne/imghost-frontend/util" - "github.com/gorilla/mux" - "net/http" -) - -func GetAlbumImage(env environment.FrontendEnvironment) http.Handler { - return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { - vars := mux.Vars(request) - albumImage, err := env.Repositories.AlbumImages.Get(vars["albumId"], vars["imageId"]) - if err == sql.ErrNoRows { - http.NotFound(writer, request) - return - } else if err != nil { - http.Error(writer, err.Error(), http.StatusInternalServerError) - return - } - - util.ReturnJson(writer, albumImage) - }) -} diff --git a/api/albumimage_list.go b/api/albumimage_list.go deleted file mode 100644 index 9782852..0000000 --- a/api/albumimage_list.go +++ /dev/null @@ -1,25 +0,0 @@ -package api - -import ( - "database/sql" - "git.kuschku.de/justjanne/imghost-frontend/environment" - "git.kuschku.de/justjanne/imghost-frontend/util" - "github.com/gorilla/mux" - "net/http" -) - -func ListAlbumImages(env environment.FrontendEnvironment) http.Handler { - return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { - vars := mux.Vars(request) - albumImages, err := env.Repositories.AlbumImages.List(vars["albumId"]) - if err == sql.ErrNoRows { - http.NotFound(writer, request) - return - } else if err != nil { - http.Error(writer, err.Error(), http.StatusInternalServerError) - return - } - - util.ReturnJson(writer, albumImages) - }) -} diff --git a/cmd/frontend/main.go b/cmd/frontend/main.go index 2fc245d..c050e6e 100644 --- a/cmd/frontend/main.go +++ b/cmd/frontend/main.go @@ -65,12 +65,6 @@ func main() { api.DeleteAlbum(env)).Methods(http.MethodDelete, http.MethodOptions) // Album Image API - router.Handle( - "/api/v1/albums/{albumId}/images", - api.ListAlbumImages(env)).Methods(http.MethodGet, http.MethodOptions) - router.Handle( - "/api/v1/albums/{albumId}/images/{imageId}", - api.GetAlbumImage(env)).Methods(http.MethodGet, http.MethodOptions) router.Handle( "/api/v1/albums/{albumId}/images/{imageId}", api.UpdateAlbumImage(env)).Methods(http.MethodPost, http.MethodOptions) diff --git a/model/album.go b/model/album.go index 75da1e6..ba560d1 100644 --- a/model/album.go +++ b/model/album.go @@ -6,12 +6,13 @@ import ( ) type Album struct { - Id string `json:"id" db:"id"` - Owner string `json:"owner" db:"owner"` - Title string `json:"title" db:"title"` - Description string `json:"description" db:"description"` - CreatedAt time.Time `json:"created_at" db:"created_at"` - UpdatedAt time.Time `json:"updated_at" db:"updated_at"` + Id string `json:"id" db:"id"` + Owner string `json:"owner" db:"owner"` + Title string `json:"title" db:"title"` + Description string `json:"description" db:"description"` + CreatedAt time.Time `json:"created_at" db:"created_at"` + UpdatedAt time.Time `json:"updated_at" db:"updated_at"` + Images []AlbumImage `json:"images"` } func (album Album) VerifyOwner(user User) error { diff --git a/model/album_image.go b/model/album_image.go index b757f7f..5d3b09f 100644 --- a/model/album_image.go +++ b/model/album_image.go @@ -1,8 +1,19 @@ package model +import ( + "git.kuschku.de/justjanne/imghost-frontend/configuration" + "git.kuschku.de/justjanne/imghost-frontend/storage" +) + type AlbumImage struct { Album string `json:"album" db:"album"` Image string `json:"image" db:"image"` Title string `json:"title" db:"title"` Description string `json:"description" db:"description"` + Url string `json:"url"` +} + +func (image *AlbumImage) LoadUrl(storage storage.Storage, config configuration.StorageConfiguration) (err error) { + image.Url = storage.UrlFor(config.ImageBucket, image.Image).String() + return } diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 76da868..8fae9dd 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -1,6 +1,6 @@ import React from 'react'; import './App.css'; -import ImageList from "./ImageList"; +import ImageList from "./components/ImageList"; import {BaseUrlProvider} from './api/baseUrlContext'; import {QueryClient, QueryClientProvider} from "react-query"; diff --git a/ui/src/ImageList.tsx b/ui/src/ImageList.tsx deleted file mode 100644 index ca22322..0000000 --- a/ui/src/ImageList.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react'; -import './App.css'; -import {useListImages} from "./api/useListImages"; - -export default function ImageList() { - const {status, data, error} = useListImages(); - return ( - <div> - <p>{status}</p> - <p>{error as string}</p> - <ul> - {data?.map(info => ( - <li key={info.id}> - <p>{info.id}</p> - <p>{info.owner}</p> - <p>{info.title}</p> - <p>{info.description}</p> - <p>{info.original_name}</p> - <p>{info.mime_type}</p> - <p>{info.created_at}</p> - <p>{info.updated_at}</p> - <p>{info.state}</p> - <p>{info.url}</p> - <img src={info.url+"t"} alt=""/> - </li> - ))} - </ul> - </div> - ); -} diff --git a/ui/src/api/model/Album.ts b/ui/src/api/model/Album.ts index a612891..fcd24df 100644 --- a/ui/src/api/model/Album.ts +++ b/ui/src/api/model/Album.ts @@ -1,3 +1,5 @@ +import {AlbumImage} from "./AlbumImage"; + export interface Album { id: string, owner: string, @@ -5,4 +7,5 @@ export interface Album { description: string, created_at: string, updated_at: string, + images: AlbumImage[], } diff --git a/ui/src/api/model/AlbumImage.ts b/ui/src/api/model/AlbumImage.ts index 01e165a..787d4d9 100644 --- a/ui/src/api/model/AlbumImage.ts +++ b/ui/src/api/model/AlbumImage.ts @@ -3,4 +3,5 @@ export interface AlbumImage { image: string, title: string, description: string, + url: string, } diff --git a/ui/src/api/useGetAlbum.ts b/ui/src/api/useGetAlbum.ts new file mode 100644 index 0000000..79c34a7 --- /dev/null +++ b/ui/src/api/useGetAlbum.ts @@ -0,0 +1,20 @@ +import {useQuery} from "react-query"; +import axios from "axios"; +import {useBaseUrl} from "./baseUrlContext"; +import {Album} from "./model/Album"; + +export const useGetAlbum = (albumId: string) => { + const baseUrl = useBaseUrl(); + return useQuery( + ["album", albumId], + () => axios.get<Album>( + `api/v1/albums/${albumId}`, + { + baseURL: baseUrl + } + ).then(it => it.data), + { + keepPreviousData: true + } + ); +} diff --git a/ui/src/api/useGetImage.ts b/ui/src/api/useGetImage.ts new file mode 100644 index 0000000..6f6fc1b --- /dev/null +++ b/ui/src/api/useGetImage.ts @@ -0,0 +1,20 @@ +import {useQuery} from "react-query"; +import axios from "axios"; +import {useBaseUrl} from "./baseUrlContext"; +import {Image} from "./model/Image"; + +export const useGetImage = (imageId: string) => { + const baseUrl = useBaseUrl(); + return useQuery( + ["image", imageId], + () => axios.get<Image>( + `api/v1/images/${imageId}`, + { + baseURL: baseUrl + } + ).then(it => it.data), + { + keepPreviousData: true + } + ); +} diff --git a/ui/src/api/useListAlbums.ts b/ui/src/api/useListAlbums.ts new file mode 100644 index 0000000..6f40830 --- /dev/null +++ b/ui/src/api/useListAlbums.ts @@ -0,0 +1,20 @@ +import {useQuery} from "react-query"; +import axios from "axios"; +import {useBaseUrl} from "./baseUrlContext"; +import {Album} from "./model/Album"; + +export const useListAlbums = () => { + const baseUrl = useBaseUrl(); + return useQuery( + "albums", + () => axios.get<Album[]>( + "api/v1/albums", + { + baseURL: baseUrl + } + ).then(it => it.data), + { + keepPreviousData: true + } + ); +} diff --git a/ui/src/api/useListImages.ts b/ui/src/api/useListImages.ts index d0e7ccf..76d74e0 100644 --- a/ui/src/api/useListImages.ts +++ b/ui/src/api/useListImages.ts @@ -6,7 +6,7 @@ import {Image} from "./model/Image"; export const useListImages = () => { const baseUrl = useBaseUrl(); return useQuery( - "connector-deployments", + "images", () => axios.get<Image[]>( "api/v1/images", { diff --git a/ui/src/components/AlbumImageView.tsx b/ui/src/components/AlbumImageView.tsx new file mode 100644 index 0000000..a2de68b --- /dev/null +++ b/ui/src/components/AlbumImageView.tsx @@ -0,0 +1,17 @@ +import React from "react"; +import {AlbumImage} from "../api/model/AlbumImage"; + +export interface AlbumImageProps { + image: AlbumImage +} + +export default function AlbumImageView({image}: AlbumImageProps) { + return ( + <div> + <p>{image.image}</p> + <p>{image.title}</p> + <p>{image.description}</p> + <img src={image.url + "t"} alt=""/> + </div> + ) +} diff --git a/ui/src/components/AlbumList.tsx b/ui/src/components/AlbumList.tsx new file mode 100644 index 0000000..6b827d3 --- /dev/null +++ b/ui/src/components/AlbumList.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import '../App.css'; +import {useListAlbums} from "../api/useListAlbums"; +import AlbumView from "./AlbumView"; + +export default function AlbumList() { + const {status, data, error} = useListAlbums(); + return ( + <div> + <p>{status}</p> + <p>{error as string}</p> + <ul> + {data?.map(album => ( + <AlbumView + key={album.id} + album={album} + /> + ))} + </ul> + </div> + ); +} diff --git a/ui/src/components/AlbumView.tsx b/ui/src/components/AlbumView.tsx new file mode 100644 index 0000000..96546c1 --- /dev/null +++ b/ui/src/components/AlbumView.tsx @@ -0,0 +1,28 @@ +import AlbumImageView from "./AlbumImageView"; +import React from "react"; +import {Album} from "../api/model/Album"; + +export interface AlbumProps { + album: Album +} + +export default function AlbumView({album}: AlbumProps) { + return ( + <div> + <p>{album.id}</p> + <p>{album.owner}</p> + <p>{album.title}</p> + <p>{album.description}</p> + <p>{album.created_at}</p> + <p>{album.updated_at}</p> + <ul> + {album.images.map(image => ( + <AlbumImageView + key={image.image} + image={image} + /> + ))} + </ul> + </div> + ); +} diff --git a/ui/src/components/ImageList.tsx b/ui/src/components/ImageList.tsx new file mode 100644 index 0000000..f7b025d --- /dev/null +++ b/ui/src/components/ImageList.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import '../App.css'; +import {useListImages} from "../api/useListImages"; +import ImageView from "./ImageView"; + +export default function ImageList() { + const {status, data, error} = useListImages(); + return ( + <div> + <p>{status}</p> + <p>{error as string}</p> + <ul> + {data?.map(image => ( + <ImageView + key={image.id} + image={image} + /> + ))} + </ul> + </div> + ); +} diff --git a/ui/src/components/ImageView.tsx b/ui/src/components/ImageView.tsx new file mode 100644 index 0000000..83bb5c5 --- /dev/null +++ b/ui/src/components/ImageView.tsx @@ -0,0 +1,23 @@ +import {Image} from "../api/model/Image"; +import React from "react"; + +export interface ImageProps { + image: Image +} + +export default function ImageView({image}: ImageProps) { + return ( + <div> + <p>{image.id}</p> + <p>{image.owner}</p> + <p>{image.title}</p> + <p>{image.description}</p> + <p>{image.original_name}</p> + <p>{image.mime_type}</p> + <p>{image.created_at}</p> + <p>{image.updated_at}</p> + <p>{image.state}</p> + <img src={image.url + "t"} alt=""/> + </div> + ) +} -- GitLab