aboutsummaryrefslogtreecommitdiffstats
path: root/web/src/giphy.js
diff options
context:
space:
mode:
Diffstat (limited to 'web/src/giphy.js')
-rw-r--r--web/src/giphy.js107
1 files changed, 107 insertions, 0 deletions
diff --git a/web/src/giphy.js b/web/src/giphy.js
new file mode 100644
index 0000000..16dcae3
--- /dev/null
+++ b/web/src/giphy.js
@@ -0,0 +1,107 @@
+import {Component, html} from "../lib/htm/preact.js";
+import * as widgetAPI from "./widget-api.js";
+import {SearchBox} from "./search-box.js";
+
+const GIPHY_SEARCH_DEBOUNCE = 1000
+let GIPHY_API_KEY = ""
+let GIPHY_MXC_PREFIX = "mxc://giphy.mau.dev/"
+
+export function giphyIsEnabled() {
+ return GIPHY_API_KEY !== ""
+}
+
+export function setGiphyAPIKey(apiKey, mxcPrefix) {
+ GIPHY_API_KEY = apiKey
+ if (mxcPrefix) {
+ GIPHY_MXC_PREFIX = mxcPrefix
+ }
+}
+
+export class GiphySearchTab extends Component {
+ constructor(props) {
+ super(props)
+ this.state = {
+ searchTerm: "",
+ gifs: [],
+ loading: false,
+ error: null,
+ }
+ this.handleGifClick = this.handleGifClick.bind(this)
+ this.searchKeyUp = this.searchKeyUp.bind(this)
+ this.updateGifSearchQuery = this.updateGifSearchQuery.bind(this)
+ this.searchTimeout = null
+ }
+
+ async makeGifSearchRequest() {
+ try {
+ const resp = await fetch(`https://api.giphy.com/v1/gifs/search?q=${this.state.searchTerm}&api_key=${GIPHY_API_KEY}`)
+ // TODO handle error responses properly?
+ const data = await resp.json()
+ if (data.data.length === 0) {
+ this.setState({gifs: [], error: "No results"})
+ } else {
+ this.setState({gifs: data.data, error: null})
+ }
+ } catch (error) {
+ this.setState({error})
+ }
+ }
+
+ componentWillUnmount() {
+ clearTimeout(this.searchTimeout)
+ }
+
+ searchKeyUp(event) {
+ if (event.key === "Enter") {
+ clearTimeout(this.searchTimeout)
+ this.makeGifSearchRequest()
+ }
+ }
+
+ updateGifSearchQuery(event) {
+ this.setState({searchTerm: event.target.value})
+ clearTimeout(this.searchTimeout)
+ this.searchTimeout = setTimeout(() => this.makeGifSearchRequest(), GIPHY_SEARCH_DEBOUNCE)
+ }
+
+ handleGifClick(gif) {
+ widgetAPI.sendSticker({
+ "body": gif.title,
+ "info": {
+ "h": gif.images.original.height,
+ "w": gif.images.original.width,
+ "size": gif.images.original.size,
+ "mimetype": "image/webp",
+ },
+ "msgtype": "m.image",
+ "url": GIPHY_MXC_PREFIX + gif.id,
+
+ "id": gif.id,
+ "filename": gif.id + ".webp",
+ })
+ }
+
+ render() {
+ // TODO display loading state?
+ return html`
+ <${SearchBox} onInput=${this.updateGifSearchQuery} onKeyUp=${this.searchKeyUp} value=${this.state.searchTerm} placeholder="Find GIFs"/>
+ <div class="pack-list">
+ <section class="stickerpack" id="pack-giphy">
+ <div class="error">
+ ${this.state.error}
+ </div>
+ <div class="sticker-list">
+ ${this.state.gifs.map((gif) => html`
+ <div class="sticker" onClick=${() => this.handleGifClick(gif)} data-gif-id=${gif.id}>
+ <img src=${gif.images.fixed_height.url} alt=${gif.title} class="visible" data=/>
+ </div>
+ `)}
+ </div>
+ <div class="footer powered-by-giphy">
+ <img src="./res/powered-by-giphy.png" alt="Powered by GIPHY"/>
+ </div>
+ </section>
+ </div>
+ `
+ }
+}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage