commit e5e683513d3891eed7ea61ae58a856cf739bcf2a
parent 3652679b080c6751bb1e6055104fde635d5f2a58
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Fri, 15 Nov 2024 09:35:15 +0000
Edit `/models/trade-product/add` add photo upload utils. Edit app layout store subscriptions. Edit `/settings/nostr` select options. Add fetch utils. Edit routes styles.
Diffstat:
6 files changed, 165 insertions(+), 22 deletions(-)
diff --git a/src/lib/utils/fetch.ts b/src/lib/utils/fetch.ts
@@ -0,0 +1,67 @@
+import { PUBLIC_RADROOTS_URL } from "$env/static/public";
+import { http } from "$lib/client";
+import type { UploadFilePresignedUrl } from "@radroots/svelte-lib";
+import { err_msg, type ErrorMessage, type FilePath, type ResultPass } from "@radroots/utils";
+
+export const fetch_uploads_presigned_url = async (opts: FilePath): Promise<
+ | UploadFilePresignedUrl
+ | ErrorMessage<string>
+> => {
+ try {
+ const { file_name, mime_type } = opts;
+ const res = await http.fetch({
+ url: `${PUBLIC_RADROOTS_URL}/public/image/upload`,
+ method: `post`,
+ data: {
+ file_name,
+ mime_type,
+ },
+ });
+ if (`err` in res) return res;
+ else if (
+ res.data &&
+ `url` in res.data &&
+ typeof res.data.url === `string` &&
+ `storage_key` in res.data &&
+ typeof res.data.storage_key === `string` &&
+ `file_name` in res.data &&
+ typeof res.data.file_name === `string`
+ ) {
+ return {
+ url: res.data.url,
+ storage_key: res.data.storage_key,
+ file_name: res.data.file_name,
+ };
+ }
+ return err_msg(`request_failure`);
+ } catch (e) {
+ console.log(`(error) fetch_uploads_presigned_url `, e);
+ return err_msg(`network_failure`);
+ }
+};
+
+export const fetch_put_upload = async (opts: {
+ url: string;
+ file_data: Uint8Array;
+ mime_type: string;
+}): Promise<ResultPass | ErrorMessage<string>> => {
+ try {
+ const { url, file_data, mime_type } = opts;
+ const res = await http.fetch({
+ url,
+ method: `put`,
+ headers: {
+ "Content-Type": mime_type,
+ },
+ data_bin: file_data,
+ });
+ if (`err` in res) return res;
+ else if (res && res.status === 200) {
+ return { pass: true };
+ }
+ return err_msg(`request_failure`);
+ } catch (e) {
+ console.log(`(error) fetch_put_upload `, e);
+ return err_msg(`network_failure`);
+ }
+};
diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte
@@ -1,17 +1,17 @@
<script lang="ts">
- import { geoc } from "$lib/client";
- import { app_cfg_type, app_geoc, app_splash } from "@radroots/svelte-lib";
+ import { geoc, notification } from "$lib/client";
+ import {
+ app_cfg_type,
+ app_geoc,
+ app_splash,
+ sleep,
+ } from "@radroots/svelte-lib";
import { onMount } from "svelte";
onMount(async () => {
try {
const geoc_connected = await geoc.connect();
app_geoc.set(!!geoc_connected);
-
- /*
- await sleep(4000);
- await notification.init();
- */
} catch (e) {
console.log(`e (app) onMount`, e);
} finally {
@@ -20,7 +20,13 @@
});
app_cfg_type.subscribe(async (_app_cfg_type) => {
- console.log(`_app_cfg_type `, _app_cfg_type);
+ //@todo
+ });
+
+ app_splash.subscribe(async (_app_splash) => {
+ if (_app_splash) return;
+ await sleep(4000);
+ await notification.init();
});
</script>
diff --git a/src/routes/(app)/+layout.ts b/src/routes/(app)/+layout.ts
@@ -5,7 +5,6 @@ import type { LayoutLoad, LayoutLoadEvent } from './$types';
export const load: LayoutLoad = async ({ url }: LayoutLoadEvent) => {
try {
- console.log(`(load) (app) `, url.pathname)
const ks_nostr_publickey = await keystore.get(
ks.keys.nostr_publickey,
);
diff --git a/src/routes/(app)/models/trade-product/+page.svelte b/src/routes/(app)/models/trade-product/+page.svelte
@@ -63,7 +63,7 @@
{#if ld && ld.results.length > 0}
<LayoutView>
- <LayoutTrellis>
+ <LayoutTrellis basis={{ classes: `pt-8` }}>
{#each ld.results as li, li_i}
<TradeProductListCard
basis={{
@@ -90,8 +90,8 @@
ld && ld?.results?.length > 0
? {
label: {
- value: `${$t(`common.add`)}`,
- classes: `tap-color`,
+ value: `${$t(`common.add_new`)}`,
+ classes: `tap-color capitalize`,
},
callback: async () => {
await route(`/models/trade-product/add`);
diff --git a/src/routes/(app)/models/trade-product/add/+page.svelte b/src/routes/(app)/models/trade-product/add/+page.svelte
@@ -1,5 +1,5 @@
<script lang="ts">
- import { db, dialog, geol } from "$lib/client";
+ import { db, dialog, fs, geol } from "$lib/client";
import ImageUploadControl from "$lib/components/image_upload_control.svelte";
import ImageUploadEditEnvelope from "$lib/components/image_upload_edit_envelope.svelte";
import MapPointSelectEnvelope from "$lib/components/map_point_select_envelope.svelte";
@@ -7,6 +7,10 @@
import TradeFieldDisplayKv from "$lib/components/trade_field_display_kv.svelte";
import { ascii } from "$lib/conf";
import { el_focus } from "$lib/utils/client";
+ import {
+ fetch_put_upload,
+ fetch_uploads_presigned_url,
+ } from "$lib/utils/fetch";
import { location_gcs_to_geoc } from "$lib/utils/geocode";
import { kv_init_page, kv_sync } from "$lib/utils/kv";
import { model_location_gcs_add_geocode } from "$lib/utils/models";
@@ -58,6 +62,7 @@
num_str,
parse_currency_marker,
parse_currency_price,
+ parse_file_path,
parse_trade_key,
parse_trade_quantity_tup,
sum_currency_price,
@@ -65,6 +70,7 @@
trade_keys,
year_curr,
type CurrencyPrice,
+ type FilePath,
type GeolocationCoordinatesPoint,
type TradeKey,
type TradeQuantity,
@@ -522,13 +528,74 @@
id: location_gcs_get_c.result.id,
},
});
- if (`pass` in trade_product_location_set) {
- route(`/models/trade-product`);
+ if (!(`pass` in trade_product_location_set)) {
+ await dialog.alert(
+ `${$t(`common.failure_to_process_the_request`)}`,
+ );
return;
}
- await dialog.alert(
- `${$t(`common.failure_to_process_the_request`)}`,
- );
+ const photo_path_uploads: {
+ file_name: string;
+ storage_key: string;
+ }[] = [];
+ const photo_path_uploads_err: {
+ file_path: FilePath;
+ err_trace: `url` | `put`;
+ err_msg: string;
+ }[] = [];
+ if (tradepr_photo_paths.length) {
+ for (const photo_path of tradepr_photo_paths) {
+ const file_path = parse_file_path(photo_path);
+ if (!file_path) continue;
+ const file_data = await fs.read_bin(photo_path);
+ if (!file_data) continue;
+ const uploads_presigned_url =
+ await fetch_uploads_presigned_url(file_path);
+ if (`err` in uploads_presigned_url) {
+ photo_path_uploads_err.push({
+ file_path,
+ err_trace: `url`,
+ err_msg: uploads_presigned_url.err,
+ });
+ continue;
+ }
+ const put_upload = await fetch_put_upload({
+ url: uploads_presigned_url.url,
+ file_data,
+ mime_type: file_path.mime_type,
+ });
+ if (`err` in put_upload) {
+ photo_path_uploads_err.push({
+ file_path,
+ err_trace: `put`,
+ err_msg: put_upload.err,
+ });
+ continue;
+ }
+ photo_path_uploads.push({
+ file_name: uploads_presigned_url.file_name,
+ storage_key: uploads_presigned_url.storage_key,
+ });
+ }
+ }
+ if (photo_path_uploads_err.length) {
+ await dialog.alert(
+ `${$t(`icu.there_was_a_failure_while_*`, {
+ value: `${$t(`icu.uploading_*_photos`, {
+ value:
+ photo_path_uploads_err.length ===
+ tradepr_photo_paths.length
+ ? `${$t(`common.all`)}`
+ : `${photo_path_uploads_err.length}`,
+ })}`.toLowerCase(),
+ })}`,
+ );
+ }
+ if (photo_path_uploads.length) {
+ console.log(`@todo add photo models`);
+ }
+
+ await route(`/models/trade-product`);
} catch (e) {
console.log(`(error) submit `, e);
}
diff --git a/src/routes/(app)/settings/nostr/+page.svelte b/src/routes/(app)/settings/nostr/+page.svelte
@@ -17,16 +17,20 @@
select_options: [
{
value: ascii.bullet,
- label: `Choose photo hosting`,
+ label: `${$t(`icu.choose_*`, { value: `${$t(`common.photo_hosting`)}`.toLowerCase() })}`,
disabled: true,
},
{
+ value: `^radroots`,
+ label: `https://radroots.org`,
+ },
+ {
value: `*add`,
- label: `${$t(`icu.add_*`, { value: `${$t(`common.endpoint`)}`.toLowerCase() })}`,
+ label: `${$t(`icu.add_*`, { value: `${$t(`common.upload_url`)}`.toLowerCase() })}`,
},
{
- value: `^radroots`,
- label: `https://radroots.org`,
+ value: `*disable`,
+ label: `Disable uploads`,
},
],
};