start adding the SQL approach to files, also using the Dexie approach if desired

This commit is contained in:
2025-05-26 20:26:28 -06:00
parent 3f46e3817a
commit 84cc501951
5 changed files with 224 additions and 83 deletions

View File

@@ -999,6 +999,7 @@ import {
DEFAULT_PUSH_SERVER,
IMAGE_TYPE_PROFILE,
NotificationIface,
USE_DEXIE_DB,
} from "../constants/app";
import {
db,
@@ -1012,6 +1013,7 @@ import {
DEFAULT_PASSKEY_EXPIRATION_MINUTES,
MASTER_SETTINGS_KEY,
} from "../db/tables/settings";
import * as databaseUtil from "../db/databaseUtil";
import {
clearPasskeyToken,
EndorserRateLimits,
@@ -1030,6 +1032,7 @@ import {
} from "../libs/util";
import { UserProfile } from "@/libs/partnerServer";
import { logger } from "../utils/logger";
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
const inputImportFileNameRef = ref<Blob>();
@@ -1145,9 +1148,14 @@ export default class AccountViewView extends Vue {
if (error.status === 404) {
// this is ok: the profile is not yet created
} else {
logConsoleAndDb(
databaseUtil.logConsoleAndDb(
"Error loading profile: " + errorStringForLog(error),
);
if (USE_DEXIE_DB) {
logConsoleAndDb(
"Error loading profile: " + errorStringForLog(error),
);
}
this.$notify(
{
group: "alert",
@@ -1224,8 +1232,12 @@ export default class AccountViewView extends Vue {
* Initializes component state with values from the database or defaults.
*/
async initializeState() {
await db.open();
const settings = await retrieveSettingsForActiveAccount();
let settings = await databaseUtil.retrieveSettingsForActiveAccount();
if (USE_DEXIE_DB) {
await db.open();
settings = await retrieveSettingsForActiveAccount();
}
console.log("activeDid", settings.activeDid, "settings", settings);
this.activeDid = settings.activeDid || "";
this.apiServer = settings.apiServer || "";
@@ -1268,42 +1280,67 @@ export default class AccountViewView extends Vue {
async toggleShowContactAmounts() {
this.showContactGives = !this.showContactGives;
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
showContactGivesInline: this.showContactGives,
});
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
showContactGivesInline: this.showContactGives,
});
}
}
async toggleShowGeneralAdvanced() {
this.showGeneralAdvanced = !this.showGeneralAdvanced;
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
showGeneralAdvanced: this.showGeneralAdvanced,
});
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
showGeneralAdvanced: this.showGeneralAdvanced,
});
}
}
async toggleProdWarning() {
this.warnIfProdServer = !this.warnIfProdServer;
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
warnIfProdServer: this.warnIfProdServer,
});
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
warnIfProdServer: this.warnIfProdServer,
});
}
}
async toggleTestWarning() {
this.warnIfTestServer = !this.warnIfTestServer;
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
warnIfTestServer: this.warnIfTestServer,
});
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
warnIfTestServer: this.warnIfTestServer,
});
}
}
async toggleShowShortcutBvc() {
this.showShortcutBvc = !this.showShortcutBvc;
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
showShortcutBvc: this.showShortcutBvc,
});
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
showShortcutBvc: this.showShortcutBvc,
});
}
}
readableDate(timeStr: string) {
@@ -1314,9 +1351,18 @@ export default class AccountViewView extends Vue {
* Processes the identity and updates the component's state.
*/
async processIdentity() {
const account: Account | undefined = await retrieveAccountMetadata(
this.activeDid,
);
const platformService = PlatformServiceFactory.getInstance();
const dbAccount = await platformService.dbQuery("SELECT * FROM accounts WHERE did = ?", [this.activeDid]);
console.log("activeDid", this.activeDid, "dbAccount", dbAccount);
let account: Account | undefined = undefined;
if (dbAccount) {
account = databaseUtil.mapColumnsToValues(dbAccount.columns, dbAccount.values)[0] as Account;
}
if (USE_DEXIE_DB) {
account = await retrieveAccountMetadata(
this.activeDid,
);
}
if (account?.identity) {
const identity = JSON.parse(account.identity as string) as IIdentifier;
this.publicHex = identity.keys[0].publicKeyHex;
@@ -1359,9 +1405,14 @@ export default class AccountViewView extends Vue {
this.$refs.pushNotificationPermission as PushNotificationPermission
).open(DAILY_CHECK_TITLE, async (success: boolean, timeText: string) => {
if (success) {
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
notifyingNewActivityTime: timeText,
});
if (USE_DEXIE_DB) {
await db.settings.update(MASTER_SETTINGS_KEY, {
notifyingNewActivityTime: timeText,
});
}
this.notifyingNewActivity = true;
this.notifyingNewActivityTime = timeText;
}
@@ -1375,9 +1426,14 @@ export default class AccountViewView extends Vue {
text: "", // unused, only here to satisfy type check
callback: async (success) => {
if (success) {
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
notifyingNewActivityTime: "",
});
if (USE_DEXIE_DB) {
await db.settings.update(MASTER_SETTINGS_KEY, {
notifyingNewActivityTime: "",
});
}
this.notifyingNewActivity = false;
this.notifyingNewActivityTime = "";
}
@@ -1419,10 +1475,16 @@ export default class AccountViewView extends Vue {
DIRECT_PUSH_TITLE,
async (success: boolean, timeText: string, message?: string) => {
if (success) {
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
notifyingReminderMessage: message,
notifyingReminderTime: timeText,
});
if (USE_DEXIE_DB) {
await db.settings.update(MASTER_SETTINGS_KEY, {
notifyingReminderMessage: message,
notifyingReminderTime: timeText,
});
}
this.notifyingReminder = true;
this.notifyingReminderMessage = message || "";
this.notifyingReminderTime = timeText;
@@ -1438,10 +1500,16 @@ export default class AccountViewView extends Vue {
text: "", // unused, only here to satisfy type check
callback: async (success) => {
if (success) {
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
notifyingReminderMessage: "",
notifyingReminderTime: "",
});
if (USE_DEXIE_DB) {
await db.settings.update(MASTER_SETTINGS_KEY, {
notifyingReminderMessage: "",
notifyingReminderTime: "",
});
}
this.notifyingReminder = false;
this.notifyingReminderMessage = "";
this.notifyingReminderTime = "";
@@ -1455,30 +1523,47 @@ export default class AccountViewView extends Vue {
public async toggleHideRegisterPromptOnNewContact() {
const newSetting = !this.hideRegisterPromptOnNewContact;
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
hideRegisterPromptOnNewContact: newSetting,
});
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
hideRegisterPromptOnNewContact: newSetting,
});
}
this.hideRegisterPromptOnNewContact = newSetting;
}
public async updatePasskeyExpiration() {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
passkeyExpirationMinutes: this.passkeyExpirationMinutes,
});
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
passkeyExpirationMinutes: this.passkeyExpirationMinutes,
});
}
clearPasskeyToken();
this.passkeyExpirationDescription = tokenExpiryTimeDescription();
}
public async turnOffNotifyingFlags() {
// should tell the push server as well
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
notifyingNewActivityTime: "",
notifyingReminderMessage: "",
notifyingReminderTime: "",
});
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
notifyingNewActivityTime: "",
notifyingReminderMessage: "",
notifyingReminderTime: "",
});
}
this.notifyingNewActivity = false;
this.notifyingNewActivityTime = "";
this.notifyingReminder = false;
@@ -1518,7 +1603,10 @@ export default class AccountViewView extends Vue {
* @returns {Promise<Blob>} The generated blob object.
*/
private async generateDatabaseBlob(): Promise<Blob> {
return await db.export({ prettyJson: true });
if (USE_DEXIE_DB) {
return await db.export({ prettyJson: true });
}
throw new Error("Not implemented");
}
/**
@@ -1539,7 +1627,7 @@ export default class AccountViewView extends Vue {
private downloadDatabaseBackup(url: string) {
const downloadAnchor = this.$refs.downloadLink as HTMLAnchorElement;
downloadAnchor.href = url;
downloadAnchor.download = `${db.name}-backup.json`;
downloadAnchor.download = `${AppString.APP_NAME_NO_SPACES}-backup.json`;
downloadAnchor.click(); // doesn't work for some browsers, eg. DuckDuckGo
}
@@ -1620,7 +1708,8 @@ export default class AccountViewView extends Vue {
*/
async submitImportFile() {
if (inputImportFileNameRef.value != null) {
await db
if (USE_DEXIE_DB) {
await db
.delete()
.then(async () => {
// BulkError: settings.bulkAdd(): 1 of 21 operations failed. Errors: ConstraintError: Key already exists in the object store.
@@ -1640,6 +1729,9 @@ export default class AccountViewView extends Vue {
-1,
);
});
} else {
throw new Error("Not implemented");
}
}
}
@@ -1727,7 +1819,13 @@ export default class AccountViewView extends Vue {
if (!this.isRegistered) {
// the user was not known to be registered, but now they are (because we got no error) so let's record it
try {
await updateAccountSettings(did, { isRegistered: true });
await databaseUtil.updateAccountSettings(did, { isRegistered: true });
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
isRegistered: true,
});
}
this.isRegistered = true;
} catch (err) {
logger.error("Got an error updating settings:", err);
@@ -1787,26 +1885,41 @@ export default class AccountViewView extends Vue {
}
async onClickSaveApiServer() {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
apiServer: this.apiServerInput,
});
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
apiServer: this.apiServerInput,
});
}
this.apiServer = this.apiServerInput;
}
async onClickSavePartnerServer() {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
partnerApiServer: this.partnerApiServerInput,
});
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
partnerApiServer: this.partnerApiServerInput,
});
}
this.partnerApiServer = this.partnerApiServerInput;
}
async onClickSavePushServer() {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
webPushServer: this.webPushServerInput,
});
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
webPushServer: this.webPushServerInput,
});
}
this.webPushServer = this.webPushServerInput;
this.$notify(
{
@@ -1822,10 +1935,15 @@ export default class AccountViewView extends Vue {
openImageDialog() {
(this.$refs.imageMethodDialog as ImageMethodDialog).open(
async (imgUrl) => {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
profileImageUrl: imgUrl,
});
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
profileImageUrl: imgUrl,
});
}
this.profileImageUrl = imgUrl;
//console.log("Got image URL:", imgUrl);
},
@@ -1886,10 +2004,15 @@ export default class AccountViewView extends Vue {
// keep the imageUrl in localStorage so the user can try again if they want
}
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
await databaseUtil.updateDefaultSettings({
profileImageUrl: undefined,
});
if (USE_DEXIE_DB) {
await db.open();
await db.settings.update(MASTER_SETTINGS_KEY, {
profileImageUrl: undefined,
});
}
this.profileImageUrl = undefined;
} catch (error) {
@@ -1978,7 +2101,10 @@ export default class AccountViewView extends Vue {
throw Error("Profile not saved");
}
} catch (error) {
logConsoleAndDb("Error saving profile: " + errorStringForLog(error));
databaseUtil.logConsoleAndDb("Error saving profile: " + errorStringForLog(error));
if (USE_DEXIE_DB) {
logConsoleAndDb("Error saving profile: " + errorStringForLog(error));
}
const errorMessage: string =
error.response?.data?.error?.message ||
error.response?.data?.error ||
@@ -2068,7 +2194,10 @@ export default class AccountViewView extends Vue {
throw Error("Profile not deleted");
}
} catch (error) {
logConsoleAndDb("Error deleting profile: " + errorStringForLog(error));
databaseUtil.logConsoleAndDb("Error deleting profile: " + errorStringForLog(error));
if (USE_DEXIE_DB) {
logConsoleAndDb("Error deleting profile: " + errorStringForLog(error));
}
const errorMessage: string =
error.response?.data?.error?.message ||
error.response?.data?.error ||