refactor(types): improve type safety and eliminate type assertions

- Replace type assertions with proper type guards in ProfileService
- Add isAxiosError type guard and improve error handling
- Clean up formatting and improve type safety in deepLinks service
- Remove type assertions in AccountViewView Vue component
- Improve code formatting and consistency across services
This commit is contained in:
Matthew Raymer
2025-08-19 03:37:20 +00:00
parent bc1214e9db
commit 9384f0083a
3 changed files with 84 additions and 41 deletions

View File

@@ -174,16 +174,18 @@
:aria-busy="loadingProfile || savingProfile"
></textarea>
<div class="flex items-center mb-4">
<input
v-model="includeUserProfileLocation"
type="checkbox"
class="mr-2"
@change="onLocationCheckboxChange"
/>
<label for="includeUserProfileLocation">Include Location</label>
<span class="text-xs text-slate-400 ml-2">(Debug: {{ isMapReady ? 'Map Ready' : 'Map Loading' }})</span>
</div>
<div class="flex items-center mb-4">
<input
v-model="includeUserProfileLocation"
type="checkbox"
class="mr-2"
@change="onLocationCheckboxChange"
/>
<label for="includeUserProfileLocation">Include Location</label>
<span class="text-xs text-slate-400 ml-2"
>(Debug: {{ isMapReady ? "Map Ready" : "Map Loading" }})</span
>
</div>
<div v-if="includeUserProfileLocation" class="mb-4 aspect-video">
<p class="text-sm mb-2 text-slate-500">
The location you choose will be shared with the world until you remove
@@ -918,15 +920,18 @@ export default class AccountViewView extends Vue {
created() {
this.notify = createNotifyHelpers(this.$notify);
// Fix Leaflet icon issues in modern bundlers
// This prevents the "Cannot read properties of undefined (reading 'Default')" error
if (L.Icon.Default) {
delete (L.Icon.Default.prototype as any)._getIconUrl;
delete (L.Icon.Default.prototype as { _getIconUrl?: unknown })
._getIconUrl;
L.Icon.Default.mergeOptions({
iconRetinaUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon-2x.png',
iconUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png',
shadowUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-shadow.png',
iconRetinaUrl:
"https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon-2x.png",
iconUrl: "https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png",
shadowUrl:
"https://unpkg.com/leaflet@1.7.1/dist/images/marker-shadow.png",
});
}
}
@@ -955,7 +960,7 @@ export default class AccountViewView extends Vue {
this.userProfileLatitude = profile.latitude;
this.userProfileLongitude = profile.longitude;
this.includeUserProfileLocation = profile.includeLocation;
// Initialize map ready state if location is included
if (profile.includeLocation) {
this.isMapReady = false; // Will be set to true when map is ready
@@ -1543,12 +1548,18 @@ export default class AccountViewView extends Vue {
try {
logger.debug("Map ready event fired, map object:", map);
// doing this here instead of on the l-map element avoids a recentering after a drag then zoom at startup
const zoom = this.userProfileLatitude && this.userProfileLongitude ? 12 : 2;
const zoom =
this.userProfileLatitude && this.userProfileLongitude ? 12 : 2;
const lat = this.userProfileLatitude || 0;
const lng = this.userProfileLongitude || 0;
map.setView([lat, lng], zoom);
this.isMapReady = true;
logger.debug("Map ready state set to true, coordinates:", [lat, lng], "zoom:", zoom);
logger.debug(
"Map ready state set to true, coordinates:",
[lat, lng],
"zoom:",
zoom,
);
} catch (error) {
logger.error("Error in onMapReady:", error);
this.isMapReady = true; // Set to true even on error to prevent infinite loading
@@ -1560,7 +1571,7 @@ export default class AccountViewView extends Vue {
// Check if map ref is available
const mapRef = this.$refs.profileMap;
logger.debug("Map ref:", mapRef);
// Try to set map ready after component is mounted
setTimeout(() => {
this.isMapReady = true;
@@ -1597,9 +1608,9 @@ export default class AccountViewView extends Vue {
longitude: this.userProfileLongitude,
includeLocation: this.includeUserProfileLocation,
};
logger.debug("Saving profile data:", profileData);
const success = await this.profileService.saveProfile(
this.activeDid,
profileData,
@@ -1628,7 +1639,7 @@ export default class AccountViewView extends Vue {
this.userProfileLatitude = updated.latitude;
this.userProfileLongitude = updated.longitude;
this.includeUserProfileLocation = updated.includeLocation;
// Reset map ready state when toggling location
if (!updated.includeLocation) {
this.isMapReady = false;
@@ -1679,7 +1690,7 @@ export default class AccountViewView extends Vue {
}
} catch (error) {
logger.error("Error in deleteProfile component method:", error);
// Show more specific error message if available
if (error instanceof Error) {
this.notify.error(error.message);
@@ -1710,7 +1721,10 @@ export default class AccountViewView extends Vue {
onLocationCheckboxChange(): void {
try {
logger.debug("Location checkbox changed, new value:", this.includeUserProfileLocation);
logger.debug(
"Location checkbox changed, new value:",
this.includeUserProfileLocation,
);
if (!this.includeUserProfileLocation) {
// Location checkbox was unchecked, clean up map state
this.isMapReady = false;
@@ -1721,7 +1735,7 @@ export default class AccountViewView extends Vue {
// Location checkbox was checked, start map initialization timeout
this.isMapReady = false;
logger.debug("Location checked, starting map initialization timeout");
// Try to set map ready after a short delay to allow Vue to render
setTimeout(() => {
if (!this.isMapReady) {
@@ -1729,7 +1743,7 @@ export default class AccountViewView extends Vue {
this.isMapReady = true;
}
}, 1000); // 1 second delay
this.handleMapInitFailure();
}
} catch (error) {