@sneat/components 0.27.0 → 0.27.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -107,7 +107,7 @@ export class UserCountryComponent extends SneatBaseComponent {
107
107
  this.$userCountryID.set(countryID);
108
108
  },
109
109
  error: (err) => {
110
- this.errorLogger.logError('UserCountryComponent: Failed to set user country', err);
110
+ this.errorLogger.logError(err, 'UserCountryComponent: Failed to set user country');
111
111
  this.$saving.set(false);
112
112
  },
113
113
  });
@@ -1 +1 @@
1
- {"version":3,"file":"user-country.component.js","sourceRoot":"","sources":["../../../../../../libs/components/src/lib/user-country/user-country.component.ts","../../../../../../libs/components/src/lib/user-country/user-country.component.html"],"names":[],"mappings":"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","sourcesContent":["import { HttpClient, HttpHeaders } from '@angular/common/http';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n OnDestroy,\n signal,\n inject,\n input\n} from '@angular/core';\nimport {\n IonButton,\n IonCard,\n IonCardContent,\n IonCardHeader,\n IonCardTitle,\n IonIcon,\n IonLabel,\n} from '@ionic/angular';\nimport { SneatUserService } from '@sneat/auth-core';\nimport { ClassName, SneatBaseComponent } from '@sneat/ui';\nimport { map, race, takeUntil } from 'rxjs';\nimport { CountryInputComponent } from '../country-input';\nimport { ICountry, CountriesLoaderService } from '../country-selector';\n\nlet ipCountryCached: string | undefined; // TODO: Should have expiration?\n\n@Component({\n imports: [\n CountryInputComponent,\n IonCardContent,\n IonCardHeader,\n IonCardTitle,\n IonButton,\n IonIcon,\n IonLabel,\n IonCard,\n ],\n providers: [\n {\n provide: ClassName,\n useValue: 'UserCountryComponent',\n },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'sneat-user-country',\n templateUrl: './user-country.component.html',\n})\nexport class UserCountryComponent\n extends SneatBaseComponent\n implements OnDestroy\n{\n private readonly httpClient = inject(HttpClient);\n private readonly userService = inject(SneatUserService);\n private readonly countriesLoader = inject(CountriesLoaderService);\n\n protected readonly $ipCountryID = signal('');\n protected readonly $ipCountry = signal<ICountry | undefined>(undefined);\n\n protected readonly $userCountryID = signal<string>('');\n protected readonly $userHasCountry = computed(() => {\n const userCountryID = this.$userCountryID();\n return !!userCountryID && userCountryID !== '--';\n });\n\n protected isCountryDetectionStarted = false;\n protected readonly $detectingCountry = signal(false);\n protected readonly $saving = signal(false);\n\n public readonly doNotHide = input(false);\n\n private trackUserRecord(): void {\n this.userService.userState\n .pipe(takeUntil(this.destroyed$))\n .subscribe((user) => {\n if (user.record) {\n this.$userCountryID.set(user?.record?.countryID || '--');\n }\n });\n }\n\n constructor() {\n super();\n this.trackUserRecord();\n // this.getIpCountry();\n effect(() => {\n const userCountryID = this.$userCountryID();\n if (\n userCountryID === '--' &&\n // It looks like using signal here can cause an infinite loop\n !this.isCountryDetectionStarted\n ) {\n this.getIpCountry();\n }\n });\n }\n\n protected onCountryOfResidenceChanged(countryID: string): void {\n this.setCountry(countryID);\n }\n\n private getIpCountry(): void {\n if (this.isCountryDetectionStarted) {\n return;\n }\n this.isCountryDetectionStarted = true;\n if (ipCountryCached) {\n this.$ipCountryID.set(ipCountryCached);\n this.countriesLoader.getCountryByID(ipCountryCached).then((country) => {\n this.$ipCountry.set(country);\n });\n return;\n }\n this.$detectingCountry.set(true);\n // console.log('UserCountryComponent: Detecting IP country...');\n race(\n this.httpClient\n .get<string>('https://ipapi.co/country', {\n headers: new HttpHeaders({\n Accept: 'text/plain',\n }),\n responseType: 'text' as 'json',\n })\n .pipe(\n map((country) => ({ source: 'https://ipapi.co/country', country })),\n ),\n ).subscribe({\n next: (response) => {\n // console.log('UserCountryComponent: Got IP country:', response);\n const ipCountryID = response.country;\n ipCountryCached = ipCountryID;\n this.$ipCountryID.set(ipCountryID);\n this.countriesLoader.getCountryByID(ipCountryID).then((country) => {\n this.$ipCountry.set(country);\n });\n this.$detectingCountry.set(false);\n },\n error: (err) => {\n this.$detectingCountry.set(false);\n // console.error('UserCountryComponent: Failed to get IP country', err);\n this.errorLogger.logError(\n err,\n 'UserCountryComponent: Failed to get IP country',\n {\n show: false,\n },\n );\n },\n });\n }\n\n protected setCountry(countryID?: string): void {\n if (!countryID) {\n return;\n }\n this.$saving.set(true);\n this.userService.setUserCountry(countryID).subscribe({\n next: () => {\n // console.log('UserCountryComponent: User country set to', countryID);\n this.$userCountryID.set(countryID);\n },\n error: (err) => {\n this.errorLogger.logError(\n 'UserCountryComponent: Failed to set user country',\n err,\n );\n this.$saving.set(false);\n },\n });\n }\n}\n","@let userCountryID = $userCountryID();\n@let userHasCountry = $userHasCountry();\n\n@if (doNotHide() || ($ipCountry() && !userHasCountry)) {\n <ion-card>\n @if (userHasCountry || !$ipCountry()) {\n <ion-card-content>\n <sneat-country-input\n label=\"Country of residence\"\n [canReset]=\"false\"\n [countryID]=\"userCountryID || ''\"\n (countryIDChange)=\"onCountryOfResidenceChanged($event)\"\n />\n </ion-card-content>\n } @else {\n <ion-card-header>\n <ion-card-title>\n Is {{ $ipCountry()?.emoji }} {{ $ipCountry()?.title }} your country of\n residence?\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-button\n [disabled]=\"$saving()\"\n color=\"primary\"\n class=\"ion-padding-end\"\n (click)=\"setCountry($ipCountryID())\"\n >\n <ion-icon name=\"checkmark-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\"\n ><b\n >Yes, my primary residence is in {{ $ipCountry()?.title }}\n {{ $ipCountry()?.emoji }}</b\n ></ion-label\n >\n </ion-button>\n <ion-button color=\"light\" [disabled]=\"$saving()\">\n <ion-icon name=\"list-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\">Choose county</ion-label>\n </ion-button>\n </ion-card-content>\n }\n </ion-card>\n}\n"]}
1
+ {"version":3,"file":"user-country.component.js","sourceRoot":"","sources":["../../../../../../libs/components/src/lib/user-country/user-country.component.ts","../../../../../../libs/components/src/lib/user-country/user-country.component.html"],"names":[],"mappings":"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","sourcesContent":["import { HttpClient, HttpHeaders } from '@angular/common/http';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n effect,\n OnDestroy,\n signal,\n inject,\n input\n} from '@angular/core';\nimport {\n IonButton,\n IonCard,\n IonCardContent,\n IonCardHeader,\n IonCardTitle,\n IonIcon,\n IonLabel,\n} from '@ionic/angular';\nimport { SneatUserService } from '@sneat/auth-core';\nimport { ClassName, SneatBaseComponent } from '@sneat/ui';\nimport { map, race, takeUntil } from 'rxjs';\nimport { CountryInputComponent } from '../country-input';\nimport { ICountry, CountriesLoaderService } from '../country-selector';\n\nlet ipCountryCached: string | undefined; // TODO: Should have expiration?\n\n@Component({\n imports: [\n CountryInputComponent,\n IonCardContent,\n IonCardHeader,\n IonCardTitle,\n IonButton,\n IonIcon,\n IonLabel,\n IonCard,\n ],\n providers: [\n {\n provide: ClassName,\n useValue: 'UserCountryComponent',\n },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'sneat-user-country',\n templateUrl: './user-country.component.html',\n})\nexport class UserCountryComponent\n extends SneatBaseComponent\n implements OnDestroy\n{\n private readonly httpClient = inject(HttpClient);\n private readonly userService = inject(SneatUserService);\n private readonly countriesLoader = inject(CountriesLoaderService);\n\n protected readonly $ipCountryID = signal('');\n protected readonly $ipCountry = signal<ICountry | undefined>(undefined);\n\n protected readonly $userCountryID = signal<string>('');\n protected readonly $userHasCountry = computed(() => {\n const userCountryID = this.$userCountryID();\n return !!userCountryID && userCountryID !== '--';\n });\n\n protected isCountryDetectionStarted = false;\n protected readonly $detectingCountry = signal(false);\n protected readonly $saving = signal(false);\n\n public readonly doNotHide = input(false);\n\n private trackUserRecord(): void {\n this.userService.userState\n .pipe(takeUntil(this.destroyed$))\n .subscribe((user) => {\n if (user.record) {\n this.$userCountryID.set(user?.record?.countryID || '--');\n }\n });\n }\n\n constructor() {\n super();\n this.trackUserRecord();\n // this.getIpCountry();\n effect(() => {\n const userCountryID = this.$userCountryID();\n if (\n userCountryID === '--' &&\n // It looks like using signal here can cause an infinite loop\n !this.isCountryDetectionStarted\n ) {\n this.getIpCountry();\n }\n });\n }\n\n protected onCountryOfResidenceChanged(countryID: string): void {\n this.setCountry(countryID);\n }\n\n private getIpCountry(): void {\n if (this.isCountryDetectionStarted) {\n return;\n }\n this.isCountryDetectionStarted = true;\n if (ipCountryCached) {\n this.$ipCountryID.set(ipCountryCached);\n this.countriesLoader.getCountryByID(ipCountryCached).then((country) => {\n this.$ipCountry.set(country);\n });\n return;\n }\n this.$detectingCountry.set(true);\n // console.log('UserCountryComponent: Detecting IP country...');\n race(\n this.httpClient\n .get<string>('https://ipapi.co/country', {\n headers: new HttpHeaders({\n Accept: 'text/plain',\n }),\n responseType: 'text' as 'json',\n })\n .pipe(\n map((country) => ({ source: 'https://ipapi.co/country', country })),\n ),\n ).subscribe({\n next: (response) => {\n // console.log('UserCountryComponent: Got IP country:', response);\n const ipCountryID = response.country;\n ipCountryCached = ipCountryID;\n this.$ipCountryID.set(ipCountryID);\n this.countriesLoader.getCountryByID(ipCountryID).then((country) => {\n this.$ipCountry.set(country);\n });\n this.$detectingCountry.set(false);\n },\n error: (err) => {\n this.$detectingCountry.set(false);\n // console.error('UserCountryComponent: Failed to get IP country', err);\n this.errorLogger.logError(\n err,\n 'UserCountryComponent: Failed to get IP country',\n {\n show: false,\n },\n );\n },\n });\n }\n\n protected setCountry(countryID?: string): void {\n if (!countryID) {\n return;\n }\n this.$saving.set(true);\n this.userService.setUserCountry(countryID).subscribe({\n next: () => {\n // console.log('UserCountryComponent: User country set to', countryID);\n this.$userCountryID.set(countryID);\n },\n error: (err) => {\n this.errorLogger.logError(\n err,\n 'UserCountryComponent: Failed to set user country',\n );\n this.$saving.set(false);\n },\n });\n }\n}\n","@let userCountryID = $userCountryID();\n@let userHasCountry = $userHasCountry();\n\n@if (doNotHide() || ($ipCountry() && !userHasCountry)) {\n <ion-card>\n @if (userHasCountry || !$ipCountry()) {\n <ion-card-content>\n <sneat-country-input\n label=\"Country of residence\"\n [canReset]=\"false\"\n [countryID]=\"userCountryID || ''\"\n (countryIDChange)=\"onCountryOfResidenceChanged($event)\"\n />\n </ion-card-content>\n } @else {\n <ion-card-header>\n <ion-card-title>\n Is {{ $ipCountry()?.emoji }} {{ $ipCountry()?.title }} your country of\n residence?\n </ion-card-title>\n </ion-card-header>\n <ion-card-content>\n <ion-button\n [disabled]=\"$saving()\"\n color=\"primary\"\n class=\"ion-padding-end\"\n (click)=\"setCountry($ipCountryID())\"\n >\n <ion-icon name=\"checkmark-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\"\n ><b\n >Yes, my primary residence is in {{ $ipCountry()?.title }}\n {{ $ipCountry()?.emoji }}</b\n ></ion-label\n >\n </ion-button>\n <ion-button color=\"light\" [disabled]=\"$saving()\">\n <ion-icon name=\"list-outline\" slot=\"start\" />\n <ion-label style=\"text-transform: none\">Choose county</ion-label>\n </ion-button>\n </ion-card-content>\n }\n </ion-card>\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sneat/components",
3
- "version": "0.27.0",
3
+ "version": "0.27.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },