refactor(mobile): extract normalizeFileUri to shared utility module
Address code review feedback: - Extract normalizeFileUri to mobile/src/utils/normalizeUri.ts - Import shared function in ShareContext and UploadScreen - Move os import to top of test file - Update test docstring to reflect new behavior Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
*/
|
||||
|
||||
import React, { createContext, useCallback, useContext, useState } from "react";
|
||||
import { normalizeFileUri } from "../utils/normalizeUri";
|
||||
|
||||
export interface SharedFile {
|
||||
uri: string;
|
||||
@@ -28,28 +29,6 @@ const ShareContext = createContext<ShareContextValue>({
|
||||
clearPendingFiles: () => {},
|
||||
});
|
||||
|
||||
/**
|
||||
* Aggressively normalise a file URI so that the same physical file is
|
||||
* recognised regardless of how the URI was constructed.
|
||||
*
|
||||
* - Decode percent-encoding (`%20` → ` `)
|
||||
* - Collapse consecutive slashes after the scheme (`file:////` → `file:///`)
|
||||
* - Strip trailing slashes
|
||||
*/
|
||||
function normalizeFileUri(uri: string): string {
|
||||
let norm: string;
|
||||
try {
|
||||
norm = decodeURIComponent(uri);
|
||||
} catch {
|
||||
norm = uri;
|
||||
}
|
||||
// Collapse multiple slashes after the scheme (e.g. file://// → file:///)
|
||||
norm = norm.replace(/^(file:\/\/)\/{2,}/, "$1/");
|
||||
// Strip trailing slash
|
||||
norm = norm.replace(/\/+$/, "");
|
||||
return norm;
|
||||
}
|
||||
|
||||
export function ShareProvider({ children }: { children: React.ReactNode }) {
|
||||
const [pendingFiles, setPendingFiles] = useState<SharedFile[]>([]);
|
||||
|
||||
|
||||
@@ -28,30 +28,12 @@ import {
|
||||
} from "react-native";
|
||||
import { useAuth } from "../context/AuthContext";
|
||||
import { useShare } from "../context/ShareContext";
|
||||
import { normalizeFileUri } from "../utils/normalizeUri";
|
||||
import api from "../services/api";
|
||||
|
||||
/** Statuses that indicate processing has finished (no further polling needed). */
|
||||
const TERMINAL_STATUSES = new Set(["completed", "failed", "duplicate"]);
|
||||
|
||||
/**
|
||||
* Normalise a file URI for deduplication.
|
||||
*
|
||||
* - Decode percent-encoding (`%20` → ` `)
|
||||
* - Collapse consecutive slashes after the scheme (`file:////` → `file:///`)
|
||||
* - Strip trailing slashes
|
||||
*/
|
||||
function normalizeUri(uri: string): string {
|
||||
let norm: string;
|
||||
try {
|
||||
norm = decodeURIComponent(uri);
|
||||
} catch {
|
||||
norm = uri;
|
||||
}
|
||||
norm = norm.replace(/^(file:\/\/)\/{2,}/, "$1/");
|
||||
norm = norm.replace(/\/+$/, "");
|
||||
return norm;
|
||||
}
|
||||
|
||||
interface UploadItem {
|
||||
id: string;
|
||||
filename: string;
|
||||
@@ -130,7 +112,7 @@ export default function UploadScreen() {
|
||||
// Deduplicate: skip if this exact URI was already uploaded in this session.
|
||||
// This guards against duplicate share-sheet deliveries from iOS where the
|
||||
// Linking handler and +not-found.tsx fire for the same file.
|
||||
const normUri = normalizeUri(uri);
|
||||
const normUri = normalizeFileUri(uri);
|
||||
if (uploadedUrisRef.current.has(normUri)) {
|
||||
console.debug("[uploadFile] skipping duplicate URI:", uri);
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Normalise a file URI for deduplication.
|
||||
*
|
||||
* - Decode percent-encoding (`%20` → ` `)
|
||||
* - Collapse consecutive slashes after the scheme (`file:////` → `file:///`)
|
||||
* - Strip trailing slashes
|
||||
*/
|
||||
export function normalizeFileUri(uri: string): string {
|
||||
let norm: string;
|
||||
try {
|
||||
norm = decodeURIComponent(uri);
|
||||
} catch {
|
||||
norm = uri;
|
||||
}
|
||||
// Collapse multiple slashes after the scheme (e.g. file://// → file:///)
|
||||
norm = norm.replace(/^(file:\/\/)\/{2,}/, "$1/");
|
||||
// Strip trailing slash
|
||||
norm = norm.replace(/\/+$/, "");
|
||||
return norm;
|
||||
}
|
||||
Reference in New Issue
Block a user