[ABANDONDED] Set of "apps" for the Flexor social network.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
3.0 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. import React, { FC, useState, useEffect } from 'react'
  2. import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
  3. import { faEyeSlash } from '@fortawesome/free-solid-svg-icons'
  4. import { Communicator } from '../../../communicator'
  5. import classNames from 'classnames'
  6. import { ClassDictionary } from '../../../types'
  7. import '../../../styles/default.scss'
  8. interface Props {
  9. communicator: Communicator
  10. }
  11. const App: FC<Props> = ({ communicator }) => {
  12. const maxCharacters = 256
  13. const [content, setContent] = useState('')
  14. const [cover, setCover] = useState('')
  15. const [posting, setPosting] = useState(false)
  16. const charactersLeft = maxCharacters - content.length
  17. const showCharactersLeft = charactersLeft < (maxCharacters / 2)
  18. const buttonDisabled = charactersLeft < 1 || content.length === 0 || posting
  19. const showCharactersStyle: ClassDictionary = {
  20. 'has-text-danger': charactersLeft < (maxCharacters * 0.1),
  21. }
  22. const buttonStyle: ClassDictionary = {
  23. 'button': true,
  24. 'is-primary': true,
  25. 'is-loading': posting,
  26. }
  27. useEffect(() => {
  28. const init = async () => {
  29. try {
  30. await communicator.setHeight(document.body.offsetHeight)
  31. } catch (err) {
  32. console.error('App Component: ', err)
  33. }
  34. }
  35. init()
  36. }, [])
  37. const post = async () => {
  38. if (!content.length) return
  39. try {
  40. setPosting(true)
  41. await communicator.post(true, content, cover)
  42. setContent('')
  43. setCover('')
  44. } catch (err) {
  45. console.error('App Component: ', err)
  46. }
  47. setPosting(false)
  48. }
  49. return (
  50. <div>
  51. <div className="field">
  52. <div className="control">
  53. <textarea className="textarea" placeholder="What it do?" value={content} onChange={(e) => setContent(e.target.value)} />
  54. </div>
  55. </div>
  56. <div className="field">
  57. <p className="control has-icons-left">
  58. <input className="input" type="text" placeholder="Cover Text" value={cover} onChange={(e) => setCover(e.target.value)} />
  59. <span className="icon is-small is-left">
  60. <FontAwesomeIcon icon={faEyeSlash} />
  61. </span>
  62. </p>
  63. </div>
  64. <nav className="level">
  65. <div className="level-left">
  66. <div className="level-item">
  67. {showCharactersLeft && <p className={classNames(showCharactersStyle)}>{charactersLeft} Chars Left</p>}
  68. </div>
  69. </div>
  70. <div className="level-right">
  71. <div className="level-item">
  72. <button className={classNames(buttonStyle)} onClick={() => post()} disabled={buttonDisabled}>Post!</button>
  73. </div>
  74. </div>
  75. </nav>
  76. </div>
  77. )
  78. }
  79. export default App