diff --git a/app.go b/app.go
index af53038a..30173c46 100644
--- a/app.go
+++ b/app.go
@@ -2,9 +2,29 @@ package main
import (
"context"
+ "encoding/json"
"fmt"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "sort"
)
+type RandomImage struct {
+ Message string
+ Status string
+}
+
+type AllBreeds struct {
+ Message map[string]map[string][]string
+ Status string
+}
+
+type ImagesByBreed struct {
+ Message []string
+ Status string
+}
+
// App struct
type App struct {
ctx context.Context
@@ -21,7 +41,63 @@ func (a *App) startup(ctx context.Context) {
a.ctx = ctx
}
-// Greet returns a greeting for the given name
-func (a *App) Greet(name string) string {
- return fmt.Sprintf("Hello %s, It's show time!", name)
+func (a *App) GetRandomImageUrl() string {
+ response, err := http.Get("https://dog.ceo/api/breeds/image/random")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ responseData, err := ioutil.ReadAll(response.Body)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ var data RandomImage
+ json.Unmarshal(responseData, &data)
+
+ return data.Message
+}
+
+func (a *App) GetBreedList() []string {
+ var breeds []string
+
+ response, err := http.Get("https://dog.ceo/api/breeds/list/all")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ responseData, err := ioutil.ReadAll(response.Body)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ var data AllBreeds
+ json.Unmarshal(responseData, &data)
+
+ for k := range data.Message {
+ breeds = append(breeds, k)
+ }
+
+ sort.Strings(breeds)
+
+ return breeds
+}
+
+func (a *App) GetImageUrlsByBreed(breed string) []string {
+
+ url := fmt.Sprintf("%s%s%s%s", "https://dog.ceo/api/", "breed/", breed, "/images")
+ response, err := http.Get(url)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ responseData, err := ioutil.ReadAll(response.Body)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ var data ImagesByBreed
+ json.Unmarshal(responseData, &data)
+
+ return data.Message
}
diff --git a/frontend/index.html b/frontend/index.html
index a7c0e60a..f0ebfcd1 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -4,6 +4,7 @@
wails-react-demo
+
diff --git a/frontend/package.json b/frontend/package.json
index f66ca4aa..8eda4fe5 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -10,7 +10,8 @@
},
"dependencies": {
"react": "^18.2.0",
- "react-dom": "^18.2.0"
+ "react-dom": "^18.2.0",
+ "swr":"2.0.0-rc.0"
},
"devDependencies": {
"@types/react": "^18.0.25",
@@ -19,4 +20,4 @@
"typescript": "^4.9.3",
"vite": "^3.2.4"
}
-}
\ No newline at end of file
+}
diff --git a/frontend/package.json.md5 b/frontend/package.json.md5
index 056fa1f1..bc23d28a 100755
--- a/frontend/package.json.md5
+++ b/frontend/package.json.md5
@@ -1 +1 @@
-e8868246d0965fec42f8916e85224d6b
\ No newline at end of file
+3ea1113871f7d8ed6506615c919ed32f
\ No newline at end of file
diff --git a/frontend/src/App.css b/frontend/src/App.css
index f949d9c1..4c05dbd2 100644
--- a/frontend/src/App.css
+++ b/frontend/src/App.css
@@ -1,59 +1,14 @@
-#app {
- height: 100vh;
- text-align: center;
+#App {
+ width: 100vw;
+ height: 100vh;
+ text-align: center;
+ justify-content: center;
+ margin: 0 auto;
}
-#logo {
- display: block;
- width: 50%;
- height: 50%;
- margin: auto;
- padding: 10% 0 0;
- background-position: center;
- background-repeat: no-repeat;
- background-size: 100% 100%;
- background-origin: content-box;
+p {
+ justify-content: center;
+ text-align: center;
+ align-items: center;
+ display: flex;
}
-
-.result {
- height: 20px;
- line-height: 20px;
- margin: 1.5rem auto;
-}
-
-.input-box .btn {
- width: 60px;
- height: 30px;
- line-height: 30px;
- border-radius: 3px;
- border: none;
- margin: 0 0 0 20px;
- padding: 0 8px;
- cursor: pointer;
-}
-
-.input-box .btn:hover {
- background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%);
- color: #333333;
-}
-
-.input-box .input {
- border: none;
- border-radius: 3px;
- outline: none;
- height: 30px;
- line-height: 30px;
- padding: 0 10px;
- background-color: rgba(240, 240, 240, 1);
- -webkit-font-smoothing: antialiased;
-}
-
-.input-box .input:hover {
- border: none;
- background-color: rgba(255, 255, 255, 1);
-}
-
-.input-box .input:focus {
- border: none;
- background-color: rgba(255, 255, 255, 1);
-}
\ No newline at end of file
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index a6e56f9f..2ffcdcb5 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -1,28 +1,94 @@
-import {useState} from 'react';
-import logo from './assets/images/logo-universal.png';
-import './App.css';
-import {Greet} from "../wailsjs/go/main/App";
+import {
+ GetBreedList,
+ GetImageUrlsByBreed,
+ GetRandomImageUrl,
+} from "../wailsjs/go/main/App";
+import "./App.css";
+import { useState } from "react";
+import useSWR from "swr";
+
+function BreedList({ name }: { name: string }) {
+ const {
+ isLoading,
+ data: images = [],
+ error,
+ } = useSWR(name, GetImageUrlsByBreed);
+
+ if (isLoading) return Loading
;
+
+ if (error) return Failed to fetch
;
+
+ return (
+
+ {images.map((img) => (
+ -
+
+
+ ))}
+
+ );
+}
+
+function RandomDog({ showedAt }: { showedAt: number }) {
+ const {
+ isLoading,
+ data: img,
+ error,
+ } = useSWR(`random-${showedAt}`, GetRandomImageUrl);
+
+ if (isLoading) return Loading
;
+
+ if (error) return Failed to fetch
;
+
+ return
;
+}
function App() {
- const [resultText, setResultText] = useState("Please enter your name below 👇");
- const [name, setName] = useState('');
- const updateName = (e: any) => setName(e.target.value);
- const updateResultText = (result: string) => setResultText(result);
-
- function greet() {
- Greet(name).then(updateResultText);
- }
-
- return (
-
-

-
{resultText}
-
-
-
-
-
- )
+ const {
+ isLoading,
+ data: breeds = [],
+ error,
+ } = useSWR("getBreedList", GetBreedList);
+ const [selectedBreed, setSelectedBreed] = useState<{
+ type: "random" | "list";
+ value?: string;
+ }>();
+
+ if (isLoading) return Loading
;
+
+ if (error) return Failed to fetch
;
+
+ return (
+
+
Dog API
+
+
+
+ Click on down arrow to select a breed
+
+
+
+ {selectedBreed?.value &&
}
+
+ {selectedBreed?.type === "random" &&
}
+
+ );
}
-export default App
+export default App;
diff --git a/frontend/src/style.css b/frontend/src/style.css
index 3940d6c6..6e4c2b6f 100644
--- a/frontend/src/style.css
+++ b/frontend/src/style.css
@@ -1,26 +1,19 @@
html {
- background-color: rgba(27, 38, 54, 1);
- text-align: center;
- color: white;
+ text-align: center;
}
body {
- margin: 0;
- color: white;
- font-family: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
+ margin: 0;
+ color: white;
+ font-family: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
"Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
}
@font-face {
- font-family: "Nunito";
- font-style: normal;
- font-weight: 400;
- src: local(""),
+ font-family: "Nunito";
+ font-style: normal;
+ font-weight: 400;
+ src: local(""),
url("assets/fonts/nunito-v16-latin-regular.woff2") format("woff2");
}
-
-#app {
- height: 100vh;
- text-align: center;
-}
diff --git a/frontend/wailsjs/go/main/App.d.ts b/frontend/wailsjs/go/main/App.d.ts
index 02a3bb98..999675dc 100755
--- a/frontend/wailsjs/go/main/App.d.ts
+++ b/frontend/wailsjs/go/main/App.d.ts
@@ -1,4 +1,8 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
-export function Greet(arg1:string):Promise;
+export function GetBreedList():Promise>;
+
+export function GetImageUrlsByBreed(arg1:string):Promise>;
+
+export function GetRandomImageUrl():Promise;
diff --git a/frontend/wailsjs/go/main/App.js b/frontend/wailsjs/go/main/App.js
index c71ae77c..816d2cbc 100755
--- a/frontend/wailsjs/go/main/App.js
+++ b/frontend/wailsjs/go/main/App.js
@@ -2,6 +2,14 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
-export function Greet(arg1) {
- return window['go']['main']['App']['Greet'](arg1);
+export function GetBreedList() {
+ return window['go']['main']['App']['GetBreedList']();
+}
+
+export function GetImageUrlsByBreed(arg1) {
+ return window['go']['main']['App']['GetImageUrlsByBreed'](arg1);
+}
+
+export function GetRandomImageUrl() {
+ return window['go']['main']['App']['GetRandomImageUrl']();
}
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 4e0db2de..23200e4a 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -704,6 +704,13 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
+swr@2.0.0-rc.0:
+ version "2.0.0-rc.0"
+ resolved "https://registry.yarnpkg.com/swr/-/swr-2.0.0-rc.0.tgz#4ed95e483f3b87e1f188a74e9b2c7655694d9c85"
+ integrity sha512-QOp+4Cqnb/uuLKeuRDh7aT+ws6wSWWKPqfyIpBXK8DM3IugOYeLO5v+390I0p1MIfRd0CQlAIJZBEgmHaTfDuA==
+ dependencies:
+ use-sync-external-store "^1.2.0"
+
to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
@@ -722,6 +729,11 @@ update-browserslist-db@^1.0.9:
escalade "^3.1.1"
picocolors "^1.0.0"
+use-sync-external-store@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
+ integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
+
vite@^3.2.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/vite/-/vite-3.2.4.tgz#d8c7892dd4268064e04fffbe7d866207dd24166e"
diff --git a/main.go b/main.go
index ac15b552..60b4746c 100644
--- a/main.go
+++ b/main.go
@@ -17,7 +17,7 @@ func main() {
// Create application with options
err := wails.Run(&options.App{
- Title: "Wails React Demo",
+ Title: "Dogs Api Demo",
Width: 1024,
Height: 768,
AssetServer: &assetserver.Options{