mirror of
				https://github.com/maunium/stickerpicker.git
				synced 2025-10-31 08:58:09 +01:00 
			
		
		
		
	handle resetting search field
This commit is contained in:
		
							
								
								
									
										1
									
								
								web/res/reset.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								web/res/reset.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z"/></svg> | ||||
| After Width: | Height: | Size: 313 B | 
| @@ -41,10 +41,7 @@ const supportedThemes = ["light", "dark", "black"] | ||||
|  | ||||
| const defaultState = { | ||||
| 	packs: [], | ||||
| 	filtering: { | ||||
| 		searchTerm: "", | ||||
| 		packs: [], | ||||
| 	}, | ||||
| 	searchTerm: null, | ||||
| } | ||||
|  | ||||
| class App extends Component { | ||||
| @@ -52,7 +49,7 @@ class App extends Component { | ||||
| 		super(props) | ||||
| 		this.defaultTheme = params.get("theme") | ||||
| 		this.state = { | ||||
| 			packs: defaultState.packs, | ||||
| 			...defaultState, | ||||
| 			loading: true, | ||||
| 			error: null, | ||||
| 			stickersPerRow: parseInt(localStorage.mauStickersPerRow || "4"), | ||||
| @@ -63,7 +60,6 @@ class App extends Component { | ||||
| 				stickerIDs: frequent.get(), | ||||
| 				stickers: [], | ||||
| 			}, | ||||
| 			filtering: defaultState.filtering, | ||||
| 		} | ||||
| 		if (!supportedThemes.includes(this.state.theme)) { | ||||
| 			this.state.theme = "light" | ||||
| @@ -77,6 +73,7 @@ class App extends Component { | ||||
| 		this.packListRef = null | ||||
| 		this.navRef = null | ||||
| 		this.searchStickers = this.searchStickers.bind(this) | ||||
| 		this.resetSearch = this.resetSearch.bind(this) | ||||
| 		this.sendSticker = this.sendSticker.bind(this) | ||||
| 		this.navScroll = this.navScroll.bind(this) | ||||
| 		this.reloadPacks = this.reloadPacks.bind(this) | ||||
| @@ -101,7 +98,18 @@ class App extends Component { | ||||
| 		localStorage.mauFrequentlyUsedStickerCache = JSON.stringify(stickers.map(sticker => [sticker.id, sticker])) | ||||
| 	} | ||||
|  | ||||
| 	// Search | ||||
|  | ||||
| 	resetSearch() { | ||||
| 		this.setState({ searchTerm: defaultState.searchTerm }) | ||||
| 	} | ||||
|  | ||||
| 	searchStickers(e) { | ||||
| 		if (e.key === "Escape") { | ||||
| 			this.resetSearch() | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		const sanitizeString = s => s.toLowerCase().trim() | ||||
| 		const searchTerm = sanitizeString(e.target.value) | ||||
|  | ||||
| @@ -115,11 +123,8 @@ class App extends Component { | ||||
| 		})) | ||||
|  | ||||
| 		this.setState({ | ||||
| 			filtering: { | ||||
| 				...this.state.filtering, | ||||
| 				searchTerm, | ||||
| 				packs: packsWithFilteredStickers.filter(({ stickers }) => !!stickers.length), | ||||
| 			}, | ||||
| 			filteredPacks: packsWithFilteredStickers.filter(({ stickers }) => !!stickers.length), | ||||
| 			searchTerm, | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| @@ -145,10 +150,8 @@ class App extends Component { | ||||
| 	reloadPacks() { | ||||
| 		this.imageObserver.disconnect() | ||||
| 		this.sectionObserver.disconnect() | ||||
| 		this.setState({ | ||||
| 			packs: defaultState.packs, | ||||
| 			filtering: defaultState.filtering, | ||||
| 		}) | ||||
| 		this.setState({ packs: defaultState.packs }) | ||||
| 		this.resetSearch() | ||||
| 		this._loadPacks(true) | ||||
| 	} | ||||
|  | ||||
| @@ -258,6 +261,7 @@ class App extends Component { | ||||
| 		const sticker = this.stickersByID.get(id) | ||||
| 		frequent.add(id) | ||||
| 		this.updateFrequentlyUsed() | ||||
| 		this.resetSearch() | ||||
| 		widgetAPI.sendSticker(sticker) | ||||
| 	} | ||||
|  | ||||
| @@ -267,8 +271,8 @@ class App extends Component { | ||||
|  | ||||
| 	render() { | ||||
| 		const theme = `theme-${this.state.theme}` | ||||
| 		const filterActive = !!this.state.filtering.searchTerm | ||||
| 		const packs = filterActive ? this.state.filtering.packs : [this.state.frequentlyUsed, ...this.state.packs] | ||||
| 		const filterActive = !!this.state.searchTerm | ||||
| 		const packs = filterActive ? this.state.filteredPacks : [this.state.frequentlyUsed, ...this.state.packs] | ||||
|  | ||||
| 		if (this.state.loading) { | ||||
| 			return html`<main class="spinner ${theme}"><${Spinner} size=${80} green /></main>` | ||||
| @@ -287,7 +291,7 @@ class App extends Component { | ||||
| 				${this.state.packs.map(pack => html`<${NavBarItem} id=${pack.id} pack=${pack}/>`)} | ||||
| 				<${NavBarItem} pack=${{ id: "settings", title: "Settings" }} iconOverride="settings" /> | ||||
| 			</nav> | ||||
| 			<${SearchBox} onKeyUp=${this.searchStickers} /> | ||||
| 			<${SearchBox} onKeyUp=${this.searchStickers} resetSearch=${this.resetSearch} value=${this.state.searchTerm} /> | ||||
| 			<div class="pack-list ${isMobileSafari ? "ios-safari-hack" : ""}" ref=${elem => this.packListRef = elem}> | ||||
| 				${filterActive && packs.length === 0 ? html`<div class="search-empty"><h1>No stickers match your search</h1></div>` : null} | ||||
| 				${packs.map(pack => html`<${Pack} id=${pack.id} pack=${pack} send=${this.sendSticker} />`)} | ||||
|   | ||||
| @@ -15,12 +15,19 @@ | ||||
| // along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||
| import { html } from "../lib/htm/preact.js" | ||||
|  | ||||
| export const SearchBox = ({ onKeyUp, placeholder = 'Find stickers' }) => { | ||||
| 	const component = html` | ||||
| export const SearchBox = ({ onKeyUp, resetSearch, value }) => { | ||||
| 	const className = `icon-display ${value ? 'reset-click-zone' : null}` | ||||
| 	const title = value ? 'Click to reset' : null | ||||
| 	const onClick = value ? resetSearch : null | ||||
|  | ||||
| 	const iconToDisplay = `icon-${!value ? 'search' : 'reset'}` | ||||
|  | ||||
| 	return html` | ||||
| 		<div class="search-box"> | ||||
| 			<input type="text" placeholder=${placeholder} onKeyUp=${onKeyUp} /> | ||||
| 			<span class="icon icon-search" /> | ||||
| 			<input value=${value} placeholder="Find stickers" onKeyUp=${onKeyUp} /> | ||||
| 			<div class=${className} title=${title} onClick=${onClick}> | ||||
| 				<span class="icon ${iconToDisplay}" /> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	` | ||||
| 	return component | ||||
| } | ||||
|   | ||||
| @@ -92,9 +92,12 @@ main.theme-black | ||||
|   &.icon-recent | ||||
|     --icon-image: url(../res/recent.svg) | ||||
|  | ||||
|   &.icon.icon-search | ||||
|   &.icon-search | ||||
|     --icon-image: url(../res/search.svg) | ||||
|  | ||||
|   &.icon-reset | ||||
|     --icon-image: url(../res/reset.svg) | ||||
|  | ||||
| nav | ||||
|   display: flex | ||||
|   overflow-x: auto | ||||
|   | ||||
		Reference in New Issue
	
	Block a user