Fix HomeView notification migration to use proper constants pattern

- Add NOTIFY_CONTACT_LOADING_ISSUE, NOTIFY_FEED_LOADING_ISSUE, and NOTIFY_CONFIRMATION_ERROR constants to notifications.ts
- Update HomeView.vue to import and use notification constants instead of literal strings
- Update migration templates to document constants vs literal strings pattern
- Add comprehensive documentation for notification constants usage

Ensures consistency with established pattern used in ActivityListItem.vue and other migrated components. Linter passes without errors.
This commit is contained in:
Matthew Raymer
2025-07-07 04:49:30 +00:00
parent b7f135d257
commit 3d124e13bb
9 changed files with 765 additions and 149 deletions

View File

@@ -259,7 +259,10 @@ import {
import { containsHiddenDid, isHiddenDid } from "../libs/endorserServer";
import ProjectIcon from "./ProjectIcon.vue";
import { createNotifyHelpers } from "@/utils/notify";
import { NOTIFY_PERSON_HIDDEN, NOTIFY_UNKNOWN_PERSON } from "@/constants/notifications";
import {
NOTIFY_PERSON_HIDDEN,
NOTIFY_UNKNOWN_PERSON,
} from "@/constants/notifications";
import { TIMEOUTS } from "@/utils/notify";
@Component({
@@ -284,17 +287,11 @@ export default class ActivityListItem extends Vue {
}
notifyHiddenPerson() {
this.notify.warning(
NOTIFY_PERSON_HIDDEN.message,
TIMEOUTS.STANDARD,
);
this.notify.warning(NOTIFY_PERSON_HIDDEN.message, TIMEOUTS.STANDARD);
}
notifyUnknownPerson() {
this.notify.warning(
NOTIFY_UNKNOWN_PERSON.message,
TIMEOUTS.STANDARD,
);
this.notify.warning(NOTIFY_UNKNOWN_PERSON.message, TIMEOUTS.STANDARD);
}
@Emit()
@@ -340,7 +337,7 @@ export default class ActivityListItem extends Vue {
handleConfirmClick() {
if (!this.canConfirm) {
notifyWhyCannotConfirm(
(msg, timeout) => this.notify.info(msg.text ?? '', timeout),
(msg, timeout) => this.notify.info(msg.text ?? "", timeout),
this.isRegistered,
this.record.fullClaim?.["@type"],
this.record,

View File

@@ -9,4 +9,19 @@ export const NOTIFY_PERSON_HIDDEN = {
export const NOTIFY_UNKNOWN_PERSON = {
title: "Unidentified Person",
message: "Nobody specific was recognized.",
};
};
export const NOTIFY_CONTACT_LOADING_ISSUE = {
title: "Contact Loading Issue",
message: "Some contact information may be unavailable.",
};
export const NOTIFY_FEED_LOADING_ISSUE = {
title: "Feed Loading Issue",
message: "Some feed data may be unavailable. Pull to refresh.",
};
export const NOTIFY_CONFIRMATION_ERROR = {
title: "Error",
message: "There was a problem submitting the confirmation.",
};

View File

@@ -290,7 +290,6 @@ import {
NotificationIface,
PASSKEYS_ENABLED,
} from "../constants/app";
import { logConsoleAndDb } from "../db/index";
import { Contact } from "../db/tables/contacts";
import { BoundingBox, checkIsAnyFeedFilterOn } from "../db/tables/settings";
import {
@@ -314,6 +313,12 @@ import * as serverUtil from "../libs/endorserServer";
import { logger } from "../utils/logger";
import { GiveRecordWithContactInfo } from "../interfaces/give";
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin";
import { createNotifyHelpers, TIMEOUTS } from "@/utils/notify";
import {
NOTIFY_CONTACT_LOADING_ISSUE,
NOTIFY_FEED_LOADING_ISSUE,
NOTIFY_CONFIRMATION_ERROR,
} from "@/constants/notifications";
import * as Package from "../../package.json";
interface Claim {
@@ -403,6 +408,7 @@ interface FeedError {
export default class HomeView extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
$router!: Router;
notify!: ReturnType<typeof createNotifyHelpers>;
AppString = AppString;
PASSKEYS_ENABLED = PASSKEYS_ENABLED;
@@ -441,6 +447,13 @@ export default class HomeView extends Vue {
imageCache: Map<string, Blob | null> = new Map();
showProjectsDialog = false;
/**
* Initializes notification helpers
*/
created() {
this.notify = createNotifyHelpers(this.$notify);
}
/**
* Initializes the component on mount
* Sequence:
@@ -486,7 +499,10 @@ export default class HomeView extends Vue {
try {
this.allMyDids = await retrieveAccountDids();
} catch (error) {
logConsoleAndDb(`[HomeView] Failed to retrieve DIDs: ${error}`, true);
this.$logAndConsole(
`[HomeView] Failed to retrieve DIDs: ${error}`,
true,
);
throw new Error(
"Failed to load existing identities. Please try restarting the app.",
);
@@ -499,10 +515,10 @@ export default class HomeView extends Vue {
const newDid = await generateSaveAndActivateIdentity();
this.isCreatingIdentifier = false;
this.allMyDids = [newDid];
logConsoleAndDb(`[HomeView] Created new identity: ${newDid}`);
this.$logAndConsole(`[HomeView] Created new identity: ${newDid}`);
} catch (error) {
this.isCreatingIdentifier = false;
logConsoleAndDb(
this.$logAndConsole(
`[HomeView] Failed to create new identity: ${error}`,
true,
);
@@ -519,7 +535,7 @@ export default class HomeView extends Vue {
isRegistered: false,
});
} catch (error) {
logConsoleAndDb(
this.$logAndConsole(
`[HomeView] Failed to retrieve settings: ${error}`,
true,
);
@@ -540,20 +556,15 @@ export default class HomeView extends Vue {
try {
this.loadContacts();
} catch (error) {
logConsoleAndDb(
this.$logAndConsole(
`[HomeView] Failed to retrieve contacts: ${error}`,
true,
);
this.allContacts = []; // Ensure we have a valid empty array
this.blockedContactDids = [];
this.$notify(
{
group: "alert",
type: "warning",
title: "Contact Loading Issue",
text: "Some contact information may be unavailable.",
},
5000,
this.notify.warning(
NOTIFY_CONTACT_LOADING_ISSUE.message,
TIMEOUTS.LONG,
);
}
@@ -591,7 +602,7 @@ export default class HomeView extends Vue {
this.isRegistered = true;
}
} catch (error) {
logConsoleAndDb(
this.$logAndConsole(
`[HomeView] Registration check failed: ${error}`,
true,
);
@@ -603,7 +614,7 @@ export default class HomeView extends Vue {
try {
// Start feed update in background
this.updateAllFeed().catch((error) => {
logConsoleAndDb(
this.$logAndConsole(
`[HomeView] Background feed update failed: ${error}`,
true,
);
@@ -632,20 +643,12 @@ export default class HomeView extends Vue {
this.newOffersToUserProjectsHitLimit = offersToProjects.hitLimit;
}
} catch (error) {
logConsoleAndDb(
this.$logAndConsole(
`[HomeView] Failed to initialize feed/offers: ${error}`,
true,
);
// Don't throw - we can continue with empty feed
this.$notify(
{
group: "alert",
type: "warning",
title: "Feed Loading Issue",
text: "Some feed data may be unavailable. Pull to refresh.",
},
5000,
);
this.notify.warning(NOTIFY_FEED_LOADING_ISSUE.message, TIMEOUTS.LONG);
}
} catch (error) {
this.handleError(error);
@@ -824,21 +827,15 @@ export default class HomeView extends Vue {
const errorMessage = err instanceof Error ? err.message : String(err);
const userMessage = (err as { userMessage?: string })?.userMessage;
logConsoleAndDb(
this.$logAndConsole(
`[HomeView] Initialization error: ${errorMessage}${userMessage ? ` (${userMessage})` : ""}`,
true,
);
this.$notify(
{
group: "alert",
type: "danger",
title: "Error",
text:
userMessage ||
"There was an error loading your data. Please try refreshing the page.",
},
5000,
this.notify.error(
userMessage ||
"There was an error loading your data. Please try refreshing the page.",
TIMEOUTS.LONG,
);
}
@@ -1337,16 +1334,10 @@ export default class HomeView extends Vue {
*/
private handleFeedError(e: unknown) {
logger.error("Error with feed load:", e);
this.$notify(
{
group: "alert",
type: "danger",
title: "Feed Error",
text:
(e as FeedError)?.userMessage ||
"There was an error retrieving feed data.",
},
-1,
this.notify.error(
(e as FeedError)?.userMessage ||
"There was an error retrieving feed data.",
TIMEOUTS.MODAL,
);
}
@@ -1668,15 +1659,7 @@ export default class HomeView extends Vue {
* @param message Message to display
*/
toastUser(message: string) {
this.$notify(
{
group: "alert",
type: "toast",
title: "FYI",
text: message,
},
2000,
);
this.notify.toast("FYI", message, TIMEOUTS.SHORT);
}
/**
@@ -1791,64 +1774,42 @@ export default class HomeView extends Vue {
* @param record Record to confirm
*/
async confirmClaim(record: GiveRecordWithContactInfo) {
this.$notify(
{
group: "modal",
type: "confirm",
title: "Confirm",
text: "Do you personally confirm that this is true?",
onYes: async () => {
const goodClaim = serverUtil.removeSchemaContext(
serverUtil.removeVisibleToDids(
serverUtil.addLastClaimOrHandleAsIdIfMissing(
record.fullClaim,
record.jwtId,
record.handleId,
),
this.notify.confirm(
"Do you personally confirm that this is true?",
async () => {
const goodClaim = serverUtil.removeSchemaContext(
serverUtil.removeVisibleToDids(
serverUtil.addLastClaimOrHandleAsIdIfMissing(
record.fullClaim,
record.jwtId,
record.handleId,
),
);
),
);
const confirmationClaim = {
"@context": "https://schema.org",
"@type": "AgreeAction",
object: goodClaim,
};
const confirmationClaim = {
"@context": "https://schema.org",
"@type": "AgreeAction",
object: goodClaim,
};
const result = await serverUtil.createAndSubmitClaim(
confirmationClaim,
this.activeDid,
this.apiServer,
this.axios,
);
const result = await serverUtil.createAndSubmitClaim(
confirmationClaim,
this.activeDid,
this.apiServer,
this.axios,
);
if (result.success) {
this.$notify(
{
group: "alert",
type: "success",
title: "Success",
text: "Confirmation submitted.",
},
3000,
);
if (result.success) {
this.notify.confirmationSubmitted();
// Refresh the feed to show updated confirmation status
await this.updateAllFeed();
} else {
logger.error("Error submitting confirmation:", result);
this.$notify(
{
group: "alert",
type: "danger",
title: "Error",
text: "There was a problem submitting the confirmation.",
},
5000,
);
}
},
// Refresh the feed to show updated confirmation status
await this.updateAllFeed();
} else {
logger.error("Error submitting confirmation:", result);
this.notify.error(NOTIFY_CONFIRMATION_ERROR.message, TIMEOUTS.LONG);
}
},
-1,
);
}