import { mdiClose } from '@mdi/js';
import { LitElement, TemplateResult, CSSResultGroup, html, nothing } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { SearchResults } from '../types';
import { getCoordinates } from '../utils/helpers';
// styles
import editorStyles from '../css/editor.css';
import { LunarPhaseCardEditor } from '../editor';
const ALERT_DURATION = 5 * 1000; // 5 seconds
@customElement('moon-editor-search')
export class MoonEditorSearch extends LitElement {
@property({ attribute: false }) _editor!: LunarPhaseCardEditor;
@state() _searchValue: string = '';
@state() _searchResults: SearchResults[] = [];
private _debounceTimer: number | null = null;
static get styles(): CSSResultGroup {
return [editorStyles];
}
render(): TemplateResult {
const searchInput = html`
this._handleSearchInput(ev)}
>
${this._searchValue !== ''
? html``
: nothing}
`;
const infoSuccess = html`
Search results found
`;
return html`
${searchInput}
${infoSuccess} ${this._renderSearchResults()}
`;
}
private _renderSearchResults(): TemplateResult | typeof nothing {
if (this._searchResults.length === 0) {
return nothing;
}
const results = this._searchResults.map((result) => {
return html` this._handleSearchResult(result)}>
${result.display_name}
`;
});
return html` `;
}
private _handleSearchResult(result: SearchResults): void {
console.log('search result', result);
const { lat: latitude, lon: longitude } = result;
const event = new CustomEvent('location-update', {
detail: {
latitude,
longitude,
},
bubbles: true,
composed: true,
});
this.dispatchEvent(event);
this._clearSearch();
const message = `${name} [${latitude}, ${longitude}]`;
this._setSettingsAlert(message);
}
private _setSettingsAlert(message: string, error: boolean = false): void {
const alert = this.shadowRoot?.getElementById('success-alert') as Element;
if (alert) {
alert.innerHTML = message;
alert.setAttribute('alert-type', error ? 'error' : 'info');
alert.setAttribute('style', 'display: block;');
alert.setAttribute('title', error ? '' : 'Location change');
setTimeout(() => {
alert.setAttribute('style', 'display: none;');
}, ALERT_DURATION);
}
}
private _handleSearchInput(ev: Event): void {
ev.stopPropagation();
const target = ev.target as HTMLInputElement;
this._searchValue = target.value;
// Clear any previous timer
if (this._debounceTimer) {
clearTimeout(this._debounceTimer);
}
// Set a new timer to trigger search after 300ms of inactivity
this._debounceTimer = window.setTimeout(() => {
this._refreshSearchResults(this._searchValue);
}, 700);
}
private async _refreshSearchResults(searchValue: string): Promise {
const searchValueTrimmed = searchValue.trim();
if (searchValueTrimmed.length < 2) {
return;
}
const searchResults = await getCoordinates(searchValueTrimmed);
if (searchResults) {
this._searchResults = searchResults as SearchResults[];
}
}
private _clearSearch(): void {
console.log('clear search');
this._searchValue = '';
this._searchResults = [];
}
}