Browse Source

Create a package to share code between photos and cast

Manav Rathi 1 year ago
parent
commit
4b9446a9b0

+ 7 - 2
web/docs/dependencies.md

@@ -110,7 +110,7 @@ with Next.js.
 
 
 For more details, see [translations.md](translations.md).
 For more details, see [translations.md](translations.md).
 
 
-## Meta Frameworks
+## Meta frameworks
 
 
 ### Next.js
 ### Next.js
 
 
@@ -131,7 +131,12 @@ It is more lower level than Next, but the bells and whistles it doesn't have are
 the bells and whistles (and the accompanying complexity) that we don't need in
 the bells and whistles (and the accompanying complexity) that we don't need in
 some cases.
 some cases.
 
 
-## Photos
+## Media
+
+- "jszip" is used for reading zip files in JavaScript. Live photos are zip files
+  under the hood.
+
+## Photos app specific
 
 
 ### Misc
 ### Misc
 
 

+ 3 - 0
web/packages/media/.eslintrc.js

@@ -0,0 +1,3 @@
+module.exports = {
+    extends: ["@/build-config/eslintrc-next"],
+};

+ 11 - 0
web/packages/media/README.md

@@ -0,0 +1,11 @@
+## @/media
+
+A package for sharing code between our apps that show media (photos, videos).
+
+Specifically, this is the intersection of code required by both the photos and
+cast apps.
+
+### Packaging
+
+This (internal) package exports a React TypeScript library. We rely on the
+importing project to transpile and bundle it.

+ 52 - 0
web/packages/media/live-photo.ts

@@ -0,0 +1,52 @@
+import JSZip from "jszip";
+
+class LivePhoto {
+    image: Uint8Array;
+    video: Uint8Array;
+    imageNameTitle: string;
+    videoNameTitle: string;
+}
+
+export function getFileNameWithoutExtension(filename: string) {
+    const lastDotPosition = filename.lastIndexOf(".");
+    if (lastDotPosition === -1) return filename;
+    else return filename.slice(0, lastDotPosition);
+}
+
+export function getFileExtensionWithDot(filename: string) {
+    const lastDotPosition = filename.lastIndexOf(".");
+    if (lastDotPosition === -1) return "";
+    else return filename.slice(lastDotPosition);
+}
+
+export const decodeLivePhoto = async (fileName: string, zipBlob: Blob) => {
+    const originalName = getFileNameWithoutExtension(fileName);
+    const zip = await JSZip.loadAsync(zipBlob, { createFolders: true });
+
+    const livePhoto = new LivePhoto();
+    for (const zipFilename in zip.files) {
+        if (zipFilename.startsWith("image")) {
+            livePhoto.imageNameTitle =
+                originalName + getFileExtensionWithDot(zipFilename);
+            livePhoto.image = await zip.files[zipFilename].async("uint8array");
+        } else if (zipFilename.startsWith("video")) {
+            livePhoto.videoNameTitle =
+                originalName + getFileExtensionWithDot(zipFilename);
+            livePhoto.video = await zip.files[zipFilename].async("uint8array");
+        }
+    }
+    return livePhoto;
+};
+
+export const encodeLivePhoto = async (livePhoto: LivePhoto) => {
+    const zip = new JSZip();
+    zip.file(
+        "image" + getFileExtensionWithDot(livePhoto.imageNameTitle),
+        livePhoto.image,
+    );
+    zip.file(
+        "video" + getFileExtensionWithDot(livePhoto.videoNameTitle),
+        livePhoto.video,
+    );
+    return await zip.generateAsync({ type: "uint8array" });
+};

+ 9 - 0
web/packages/media/package.json

@@ -0,0 +1,9 @@
+{
+    "name": "@/media",
+    "version": "0.0.0",
+    "private": true,
+    "dependencies": {
+        "@/next": "*",
+        "jszip": "^3.10"
+    }
+}

+ 5 - 0
web/packages/media/tsconfig.json

@@ -0,0 +1,5 @@
+{
+    "extends": "@/build-config/tsconfig-typecheck.json",
+    /* Typecheck all files with the given extensions (here or in subfolders) */
+    "include": ["**/*.ts", "**/*.tsx"]
+}

+ 1 - 1
web/yarn.lock

@@ -3252,7 +3252,7 @@ jssha@~3.3.1:
     object.assign "^4.1.4"
     object.assign "^4.1.4"
     object.values "^1.1.6"
     object.values "^1.1.6"
 
 
-jszip@3.10.1:
+jszip@3.10.1, jszip@^3.10:
   version "3.10.1"
   version "3.10.1"
   resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2"
   resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2"
   integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==
   integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==