diff --git a/api/album_get.go b/api/album_get.go index 063b8e0b4fc01d444a3967fde450e521bdf9c940..928b2b4377eeb0cf4d070cfb70cd21c047ea7f1b 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 c29898b288e3d57f20605c2b72b7c9ff938d1243..74d0f4e46d7c12fb75402633774fa7dd63914a94 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 f85a592cff15718f4fa800e40ac28eff5035638e..0000000000000000000000000000000000000000 --- 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 9782852bbcdcc71fcdcebe82bda5b1fb1a0f7860..0000000000000000000000000000000000000000 --- 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 2fc245d18135044b2227ce68886907ff7e1e653a..c050e6eb05a90d7338d41facc4e26b33a8c00267 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 75da1e6da418997525fd60c6f01e249cc90fac8d..ba560d17bd1af1b80976117d2f6de84b3b12f85c 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 b757f7fb6102e69fb73118247318900c3c0ae5f3..5d3b09fdb1ef42bd29969b958fcf1541f68b5f0b 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 76da868bf1f2b06b55ff55835bbfd3709cb6043b..8fae9ddd27f5404dc92e8139c57d74b0e89f7481 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 ca223227be3e40e00bca9d8ee265873a20e8b3bc..0000000000000000000000000000000000000000 --- 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 a612891a4168d05ca3e42a13db68d1d72e5d06e9..fcd24df627cba6169e8f327881fd5105fcb08c75 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 01e165a85a940356042174b43e695b7bf812303c..787d4d9061d0340d5a694e5c6a36feed2ebc26dc 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 0000000000000000000000000000000000000000..79c34a7bd3e383c612cf8945bcd0054a5bce3939 --- /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 0000000000000000000000000000000000000000..6f6fc1b7e460d420f598b5b1788fb9613e339bf0 --- /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 0000000000000000000000000000000000000000..6f408304ba670d975deaa071d6a910f7371b27ae --- /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 d0e7ccf3bad6ba6c4a2ae92e822d5570976c7ebd..76d74e0315118c647ef39299ecea19becf31e732 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 0000000000000000000000000000000000000000..a2de68b405822583cc3bdd03c677a0897ce6e097 --- /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 0000000000000000000000000000000000000000..6b827d3f76ad18d536698f4a08020937817027bd --- /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 0000000000000000000000000000000000000000..96546c1cb0e745800e2e698d19da7301571c57f4 --- /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 0000000000000000000000000000000000000000..f7b025d801f7c6052268586c1a3eaded0ffdd4a1 --- /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 0000000000000000000000000000000000000000..83bb5c55e38243c509a559573d70297e76368181 --- /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> + ) +}