diff --git a/package-lock.json b/package-lock.json index 0b140a7..fa756c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,6 +45,12 @@ "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", "dev": true }, + "@types/classnames": { + "version": "2.2.9", + "resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.9.tgz", + "integrity": "sha512-MNl+rT5UmZeilaPxAVs6YaPC2m6aA8rofviZbhbxpPpl61uKodfdQVsBtgJGTqGizEf02oW3tsVe7FYB8kK14A==", + "dev": true + }, "@types/clean-css": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/@types/clean-css/-/clean-css-4.2.1.tgz", @@ -1101,6 +1107,11 @@ } } }, + "classnames": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", + "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + }, "clean-css": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", diff --git a/package.json b/package.json index 2ffb265..e130977 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "build:text-app": "webpack --config src/apps/text-app/composer/webpack.config.ts" }, "devDependencies": { + "@types/classnames": "^2.2.9", "@types/html-webpack-plugin": "^3.2.1", "@types/mini-css-extract-plugin": "^0.8.0", "@types/react": "^16.9.9", @@ -32,6 +33,7 @@ "@fortawesome/fontawesome-svg-core": "^1.2.25", "@fortawesome/free-solid-svg-icons": "^5.11.2", "@fortawesome/react-fontawesome": "^0.1.7", + "classnames": "^2.2.6", "fastify": "^2.10.0", "fastify-static": "^2.5.0", "react": "^16.10.2", diff --git a/src/apps/text-app/composer/app.tsx b/src/apps/text-app/composer/app.tsx index c3dcc0b..fb79ddb 100644 --- a/src/apps/text-app/composer/app.tsx +++ b/src/apps/text-app/composer/app.tsx @@ -2,6 +2,9 @@ import React, { FC, useState, useEffect } from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { faEyeSlash } from '@fortawesome/free-solid-svg-icons' import { Communicator } from '../../../communicator' +import classNames from 'classnames' +import { ClassDictionary } from '../../../types' + import '../../../styles/default.scss' interface Props { @@ -12,11 +15,21 @@ const App: FC = ({ communicator }) => { const maxCharacters = 256 const [content, setContent] = useState('') const [cover, setCover] = useState('') + const [posting, setPosting] = useState(false) const charactersLeft = maxCharacters - content.length const showCharactersLeft = charactersLeft < (maxCharacters / 2) - const showCharactersStyle = charactersLeft > (maxCharacters * 0.1) ? 'has-text-danger' : '' - const buttonStyle = 'button is-primary is-small' + (charactersLeft < 1 ? ' is-disabled' : '') + const buttonDisabled = charactersLeft < 1 || content.length === 0 || posting + + const showCharactersStyle: ClassDictionary = { + 'has-text-danger': charactersLeft < (maxCharacters * 0.1), + } + + const buttonStyle: ClassDictionary = { + 'button': true, + 'is-primary': true, + 'is-loading': posting, + } useEffect(() => { const init = async () => { @@ -30,6 +43,21 @@ const App: FC = ({ communicator }) => { init() }, []) + const post = async () => { + if (!content.length) return + + try { + setPosting(true) + await communicator.post(true, content, cover) + setContent('') + setCover('') + } catch (err) { + console.error('App Component: ', err) + } + + setPosting(false) + } + return (
@@ -50,13 +78,13 @@ const App: FC = ({ communicator }) => { diff --git a/src/communicator/index.ts b/src/communicator/index.ts index 58ed287..fcfbe72 100644 --- a/src/communicator/index.ts +++ b/src/communicator/index.ts @@ -17,7 +17,7 @@ export interface OutgoingMessageData { } interface Listener { - resolve: (value: unknown) => void + resolve: (value?: MessageContent | PromiseLike) => void reject: (reason: any) => void once: boolean } @@ -71,7 +71,7 @@ export class Communicator { publicKey: this.publicKey, }), this.origin) - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this.listeners[name] = { resolve, reject, @@ -88,4 +88,13 @@ export class Communicator { async setHeight(height: number) { return this.postAndReceive('setHeight', { height }) } + + async post(visible: boolean, text?: string, cover?: string, data?: object) { + return this.postAndReceive('post', { + visible, + text, + cover, + data, + }) + } } diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..c87b774 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,3 @@ +export interface ClassDictionary { + [name: string]: boolean +}