Dwayne Harris 4 years ago
parent
commit
9712187d0b
  1. 44
      src/apps/gif-app/composer/app.tsx
  2. 9
      src/apps/text-app/composer/app.tsx
  3. 9
      src/communicator/index.ts
  4. 9
      src/styles/default.css
  5. 18
      src/styles/spinner.css

44
src/apps/gif-app/composer/app.tsx

@ -1,13 +1,12 @@
import React, { FC, useState, useEffect } from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faSearch } from '@fortawesome/free-solid-svg-icons'
import { Communicator, Theme } from '../../../communicator'
import { faSearch, faSpinner } from '@fortawesome/free-solid-svg-icons'
import { Communicator, Theme, InstallationSettings } from '../../../communicator'
import Gif from './gif'
import { GiphyGif } from '../../../types'
const giphyIcon = require('./giphy.png')
import '../../../styles/default.css'
import '../../../styles/spinner.css'
type APIResponse = GiphyGif[]
@ -35,6 +34,7 @@ const App: FC<Props> = ({ communicator }) => {
const [posting, setPosting] = useState(false)
const [searching, setSearching] = useState(false)
const [search, setSearch] = useState('')
const [settings, setSettings] = useState<InstallationSettings>({})
const searchD = useDebounce(search)
const [gifs, setGifs] = useState<GiphyGif[]>([])
const [selected, setSelected] = useState('')
@ -55,10 +55,14 @@ const App: FC<Props> = ({ communicator }) => {
const init = async () => {
try {
const content = await communicator.init()
if (content!.theme) setTheme(content!.theme)
if (content && content.parent && content.parent.data && content.parent.data.search) {
setSearch(content.parent.data.search)
if (content) {
if (content.settings) setSettings(content.settings)
if (content.theme) setTheme(content.theme)
if (content.parent && content.parent.data && content.parent.data.search) {
setSearch(content.parent.data.search)
}
}
await communicator.setHeight(1000)
@ -79,9 +83,26 @@ const App: FC<Props> = ({ communicator }) => {
const doSearch = async () => {
try {
setSearching(true)
const response = await fetch(`/api/gifs/search?q=${search}`)
setGifs(await response.json() as APIResponse)
} catch (err) {}
const previousSearches: string[] = settings.searches ?? []
const searches = [
search,
...previousSearches.slice(0, 9),
]
const newSettings = {
...settings,
searches,
}
await communicator.saveSettings(newSettings)
setSettings(newSettings)
} catch (err) {
console.error(err)
}
setSearching(false)
}
@ -124,6 +145,11 @@ const App: FC<Props> = ({ communicator }) => {
setPosting(false)
}
const getPlaceholder = () => {
const searches = settings.searches as string[] ?? []
return searches[0] ? `Last Search: ${searches[0]}` : 'Search'
}
return (
<div style={{ backgroundColor: theme.backgroundPrimary }}>
<div className="field">
@ -135,7 +161,7 @@ const App: FC<Props> = ({ communicator }) => {
<input
style={{ backgroundColor: theme.backgroundSecondary, borderColor: theme.secondary, color: theme.text }}
type="text"
placeholder="Search"
placeholder={getPlaceholder()}
value={search}
onChange={(e) => handleSearchChange(e.target.value)} />
</div>
@ -153,7 +179,7 @@ const App: FC<Props> = ({ communicator }) => {
<div>
<button style={{ backgroundColor: theme.primary, color: theme.primaryAlternate }} onClick={() => post()} disabled={posting || !selected}>
{posting ? <div className="spinner" style={{ width: 20 }}></div> : <span>Post</span>}
{posting ? <FontAwesomeIcon icon={faSpinner} spin /> : <span>Post</span>}
</button>
</div>
</nav>

9
src/apps/text-app/composer/app.tsx

@ -1,12 +1,11 @@
import React, { FC, useState, useEffect } from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faShieldAlt } from '@fortawesome/free-solid-svg-icons'
import { faShieldAlt, faSpinner } from '@fortawesome/free-solid-svg-icons'
import { Communicator, Post, Theme } from '../../../communicator'
import '../../../styles/default.css'
import '../../../styles/spinner.css'
const promts = [
const prompts = [
"What's going on?",
'What it do?',
"What's happening?",
@ -79,7 +78,7 @@ const App: FC<Props> = ({ communicator }) => {
<div className="control">
<textarea
style={{ backgroundColor: theme.backgroundSecondary, borderColor: theme.secondary, color: theme.text }}
placeholder="What it do?"
placeholder={prompts[Math.floor(Math.random() * prompts.length)]}
value={content}
onChange={(e) => setContent(e.target.value)} />
</div>
@ -107,7 +106,7 @@ const App: FC<Props> = ({ communicator }) => {
<div>
<button style={{ backgroundColor: theme.primary, color: theme.primaryAlternate }} onClick={() => post()} disabled={buttonDisabled}>
{posting ? <div className="spinner" style={{ width: 20 }}></div> : <span>{buttonText}</span>}
{posting ? <FontAwesomeIcon icon={faSpinner} spin /> : <span>{buttonText}</span>}
</button>
</div>
</nav>

9
src/communicator/index.ts

@ -30,6 +30,7 @@ export interface Theme {
export interface MessageContent {
[key: string]: any
settings?: InstallationSettings
height?: number
theme?: Theme
colorScheme?: string
@ -49,6 +50,10 @@ export interface OutgoingMessageData {
settings?: object
}
export interface InstallationSettings {
[key: string]: any
}
interface Listener {
resolve: (value?: MessageContent | PromiseLike<MessageContent>) => void
reject: (reason: any) => void
@ -119,6 +124,10 @@ export class Communicator {
return this.postAndReceive('setHeight', { height })
}
async saveSettings(settings: InstallationSettings) {
return this.postAndReceive('saveSettings', { settings })
}
async post(options: PostOptions) {
return this.postAndReceive('post', options)
}

9
src/styles/default.css

@ -1,14 +1,16 @@
@charset "utf-8";
@import "normalize.css";
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro&display=swap');
@import url('https://fonts.googleapis.com/css?family=Quicksand:300,400,500,600,700&display=swap');
:root {
--default-font: 'Source Sans Pro', sans-serif;
--default-font: 'Quicksand', sans-serif;
--input-padding: 0.5rem;
}
html {
font-size: 18px;
font-family: var(--default-font);
font-size: 16px;
font-weight: 300;
}
body {
@ -32,6 +34,7 @@ button {
border: none;
border-radius: 25px;
cursor: pointer;
font-family: var(--default-font);
font-size: 0.8rem;
font-weight: 700;
padding: 0.5rem 1rem;

18
src/styles/spinner.css

@ -1,18 +0,0 @@
.spinner {
width: 40px;
height: 40px;
background-color: #333;
margin: 100px auto;
animation: sk-rotateplane 1.2s infinite ease-in-out;
}
@keyframes sk-rotateplane {
0% {
transform: perspective(120px) rotateX(0deg) rotateY(0deg);
} 50% {
transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
} 100% {
transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
}
}
Loading…
Cancel
Save