summaryrefslogtreecommitdiffstats
path: root/sticker.pinapelz.com/src/giphy.js
blob: 35172bbaf37d09a5e1002a95a845c7b7c7444319 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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 = "HQku8974Uq5MZn3MZns46kXn2R4GDm75"
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