Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
commit fe55903df6f75846911dd040c8f7940079740527
Author: Viet Ngoc <[email protected]>
Date:   Thu Nov 14 22:23:44 2024 +0100

    refactor: improve search function and optimize results
  • Loading branch information
ngocjohn committed Nov 14, 2024
1 parent 0ab66a7 commit d0c0c44
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 57 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@





### Supported Localization

<details>
Expand All @@ -60,7 +58,7 @@
| `ru` | Русский | Русский |
| `sk` | Slovak | Slovenčina |

</details>
</details></details>


### View options
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"@rollup/plugin-terser": "^0.4.4",
"@typescript-eslint/eslint-plugin": "^7.15.0",
"@typescript-eslint/parser": "^7.15.0",
"country-state-city": "^3.2.1",
"devcert": "^1.2.2",
"dotenv": "^16.4.5",
"eslint": "^8.9.0",
Expand Down Expand Up @@ -79,4 +80,4 @@
"import-lang": "node scripts/generate-lang-imports.js",
"local-copy": "cp dist/lunar-phase-card.js /Volumes/config/www/dashboard-resources/lunar-phase-card.js"
}
}
}
3 changes: 1 addition & 2 deletions scripts/update-readme.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const updateReadme = () => {
const startMarker = '### Supported Localization';
const endMarker = '</details>';
const startIndex = readmeContent.indexOf(startMarker);
const endIndex = readmeContent.indexOf(endMarker) + endMarker.length;
const endIndex = readmeContent.indexOf(endMarker, startIndex);

if (startIndex === -1 || endIndex === -1) {
console.error('Localization section not found in README.md');
Expand Down Expand Up @@ -58,5 +58,4 @@ ${newTableRows}
console.log('README.md updated successfully!');
};

// Run the script
updateReadme();
103 changes: 54 additions & 49 deletions src/components/moon-editor-search.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { mdiClose, mdiMagnify } from '@mdi/js';
import { mdiClose } from '@mdi/js';
import { ICity } from 'country-state-city';
import { City } from 'country-state-city';
import { LitElement, TemplateResult, CSSResultGroup, html, nothing, css } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';

Expand All @@ -16,8 +18,6 @@ export class MoonEditorSearch extends LitElement {
@property({ attribute: false }) _editor!: LunarPhaseCardEditor;
@state() _searchValue: string = '';
@state() _searchResults: SearchResults[] = [];
@state() _searchResultsVisible = false;
@state() _toastDissmissed = false;

static get styles(): CSSResultGroup {
return [editorStyles];
Expand All @@ -28,15 +28,14 @@ export class MoonEditorSearch extends LitElement {
<ha-textfield
.autofocus=${this.autofocus}
.aria-label=${'Search'}
.placeholder=${'Enter a location'}
.placeholder=${'Search for a location, e.g. "London, UK"'}
.value=${this._searchValue || ''}
@input=${(ev: Event) => this._handleSearchInput(ev)}
@blur=${() => this._searchLocation()}
>
</ha-textfield>
${this._searchResultsVisible
${this._searchValue !== ''
? html`<ha-icon-button .path=${mdiClose} @click=${this._clearSearch}></ha-icon-button>`
: html`<ha-icon-button .path=${mdiMagnify} @click=${this._searchLocation}></ha-icon-button>`}
: nothing}
`;

const infoSuccess = html` <ha-alert
Expand All @@ -54,27 +53,13 @@ export class MoonEditorSearch extends LitElement {
</div>`;
}

private _handleAlertDismiss(ev: Event): void {
const alert = ev.target as HTMLElement;
alert.style.display = 'none';
this._toastDissmissed = true;
}

private _renderSearchResults(): TemplateResult | typeof nothing {
if (!this._searchResultsVisible || this._searchResults.length === 0) {
return html`${!this._toastDissmissed
? html` <ha-alert
alert-type="info"
dismissable
@alert-dismissed-clicked=${(ev: Event) => this._handleAlertDismiss(ev)}
>
You can get the latitude and longitude from the search with query like "London, UK".</ha-alert
>`
: nothing}`;
if (this._searchResults.length === 0) {
return nothing;
}
const results = this._searchResults.map((result) => {
return html`<li class="search-item" @click=${() => this._handleSearchResult(result)}>
${result.display_name}
${result.display_name || result.name} ${result.countryCode ? `(${result.countryCode})` : ''}
</li> `;
});

Expand All @@ -85,57 +70,77 @@ export class MoonEditorSearch extends LitElement {

private _handleSearchResult(result: SearchResults): void {
console.log('search result', result);
const { lat, lon, display_name } = result;
const resultCity = {
name: result.display_name || result.name,
latitude: result.lat || result.latitude,
longitude: result.lon || result.longitude,
};

const { name, latitude, longitude } = resultCity;

const event = new CustomEvent('location-update', {
detail: {
latitude: lat,
longitude: lon,
latitude,
longitude,
},
bubbles: true,
composed: true,
});

this.dispatchEvent(event);
this._clearSearch();
const message = `${display_name} [${lat}, ${lon}]`;
this._handleSettingsSuccess(message);
const message = `${name} [${latitude}, ${longitude}]`;
this._setSettingsAlert(message);
}

private _handleSettingsSuccess(message: string): void {
const alert = this.shadowRoot?.getElementById('success-alert') as HTMLElement;
private _setSettingsAlert(message: string, error: boolean = false): void {
const alert = this.shadowRoot?.getElementById('success-alert') as Element;
if (alert) {
alert.innerHTML = message;
alert.style.display = 'block';
alert.setAttribute('alert-type', error ? 'error' : 'info');
alert.setAttribute('style', 'display: block;');
alert.setAttribute('title', error ? '' : 'Location change');
setTimeout(() => {
alert.style.display = 'none';
alert.setAttribute('style', 'display: none;');
}, ALERT_DURATION);
}
}

private _handleSearchInput(ev: Event): void {
private async _handleSearchInput(ev: Event): Promise<void> {
ev.stopPropagation();
const target = ev.target as HTMLInputElement;
this._searchValue = target.value;
await new Promise((resolve) => setTimeout(resolve, 50));
this._refreshSearchResults(this._searchValue);
}

private async _refreshSearchResults(searchValue: string): Promise<void> {
const searchValueTrimmed = searchValue.trim();
let searchResults = this.getMatchingCities(searchValueTrimmed) as ICity[];

if (searchResults.length === 0) {
searchResults = await getCoordinates(searchValueTrimmed);
if (searchResults.length === 0) {
this._setSettingsAlert('No results found', true);
}
}

if (searchResults) {
this._searchResults = searchResults as SearchResults[];
}
}

private getMatchingCities(startsWith: string): ICity[] {
const range = 10;
const cities = City.getAllCities();
cities.sort((a, b) => a.name.localeCompare(b.name));
const filteredCities = cities.filter((city) => city.name.toLowerCase().startsWith(startsWith.toLowerCase()));
return filteredCities.slice(0, range);
}

private _clearSearch(): void {
console.log('clear search');
this._searchValue = '';
this._searchResults = [];
this._searchResultsVisible = false;
}

private async _searchLocation(): Promise<void> {
console.log('search location', this._searchValue);
const searchValue = this._searchValue;
if (!searchValue || searchValue === '') {
return;
}
this._toastDissmissed = true;
const results = await getCoordinates(searchValue);
if (results) {
this._searchResults = results;
this._searchResultsVisible = true;
}
}
}
2 changes: 1 addition & 1 deletion src/css/editor.css
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ ul.search-results {
padding-right: 0;
margin-top: 0;
margin-bottom: 0;
max-height: 500px;
max-height: 250px;
overflow-y: auto;
background-color: var(--divider-color);
}
Expand Down
1 change: 0 additions & 1 deletion src/lunar-phase-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export class LunarPhaseCard extends LitElement {
@state() _hass!: HomeAssistant;
@property({ attribute: false }) config!: LunarPhaseCardConfig;
@property({ type: Object }) protected moon!: Moon;

@state() _activeCard: PageType | null = null;
@state() selectedDate: Date | undefined;
@state() _refreshInterval: number | undefined;
Expand Down
9 changes: 9 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ICity } from 'country-state-city';
// Cutom card helpers:
import { LovelaceCardConfig, Themes, HomeAssistant, Theme } from 'custom-card-helpers';
import { HassEntity } from 'home-assistant-js-websocket';
Expand Down Expand Up @@ -171,4 +172,12 @@ export type SearchResults = {
name: string;
lat: number;
lon: number;
} & ICity;

export type ResultItem = SearchResults & {
name: string;
countryCode: string;
stateCode: string;
latitude?: string | null;
longitude?: string | null;
};

0 comments on commit d0c0c44

Please sign in to comment.