手记

婚礼回忆录:大家一起制作的婚礼相册本

婚礼的美好回忆

这是提交给Pinata挑战的。

我建造的东西

婚礼回忆录是一款专为捕捉、分享并珍藏您特别日子中的每一个珍贵瞬间而设计的应用程序!它允许婚礼宾客轻松上传照片,共同创建一个反映婚礼精髓的相册。通过使用Pinata的文件API,该应用为安全高效地上传和存储媒体提供了无缝体验。

演示

试试看这个应用的实时版本:Wedding Memories(婚礼回忆)

截图如下。

  • 上传区 — 方便选择并上传媒体文件:

如图所示:

  • 画廊视图功能 - 以响应式布局展示所有上传的记忆,

看这张图片:

  • 响应式设计 - 确保在各种设备上都有流畅的用户界面和体验

  • 下载选项: 游客可以下载他们最喜爱的瞬间,留住美好回忆。

如图所示

我的代码

你可以在这里查看该项目的全部代码。

更多详细信息

《婚礼回忆》利用Pinata的Files API来构建安全且高效的文件上传。以下是该集成的简要介绍:

  • 文件上传:用户可以轻松地从设备直接上传图片。这通过使用pinata.upload.file实现,该功能采用JWT认证以确保文件处理的安全性。上传后,上传的文件将安全存储,并生成唯一的CID以便检索。

  • 上传前的本地预览:为了提升宾客体验,婚礼照片会在上传照片前生成本地预览。此功能允许宾客确认并调整,确保上传的照片正是他们想要的。

文件成功上传后,文件会被file API渲染。这确保了内容的快速访问,访客在查看共享回忆时可以享受无缝体验。

  • 下载功能:用户现在可以直接在应用里下载最喜欢的照片,轻松将珍贵的照片保存到他们的设备中。应用内置了API接口,以安全下载照片。

API集成拆解:

这栋建筑包含几个关键的API接口,每个都专门设计用于处理特定的功能:

  • 文件上传 — 接口

这接受文件上传,并通过Pinata的上传功能进行存储。接着生成一个签名的URL来方便访问上传的文件。

import { NextResponse, NextRequest } from "next/server";
import { pinata } from "../../../../utils/config";

export async function POST(request: NextRequest) {
  try {
    const data = await request.formData();
    const file: File | null = data.get("file") as unknown as File;
    const uploadData = await pinata.upload.file(file)
    const url = await pinata.gateways.createSignedURL({
        cid: uploadData.cid,
        expires: 3600,
    });
    return NextResponse.json(url, { status: 200 });
  } catch (e) {
    console.log(e);
    return NextResponse.json(
      { error: "服务器内部错误" },
      { status: 500 }
    );
  }
}

全屏模式, 退出全屏

  • API 密钥创建 (/api/key/route.ts):

创建一个临时的API密钥,以具有将文件固定到IPFS的权限。

    /* eslint-disable @typescript-eslint/no-unused-vars */
    import { NextResponse } from "next/server";
    import { pinata } from "../../../../utils/config";

    export const dynamic = "force-dynamic";

    export async function GET() {
        try {
            const uuid = crypto.randomUUID();
            const keyData = await pinata.keys.create({
                keyName: uuid.toString(),
                permissions: {
                    endpoints: {
                        pinning: {
                            pinFileToIPFS: true,
                        },
                    },
                },
                maxUses: 1,
            })
            return NextResponse.json(keyData, { status: 200 });
        } catch (error) {
            console.log(error);
            return NextResponse.json({ text: "创建API密钥时出错:" }, { status: 500 });
        }
    }

进入全屏模式 退出全屏模式

  • 文件列表 API 路由 (/api/listfiles/route.ts):

从Pinata获取上传文件的列表,让用户可以查看图库中的所有共享文件。

    import { NextResponse } from "next/server";
    import { env } from "process";

    export const dynamic = "force-dynamic";

    export async function GET() {
      try {
        const options: RequestInit = {
          method: 'GET',
          headers: {
            Authorization: `Bearer ${env.PINATA_JWT}`, // 注:Bearer令牌用于授权请求
          },
          cache: 'no-cache'
        };

        const response = await fetch('https://api.pinata.cloud/v3/files', options);

        if (!response.ok) {
          return NextResponse.json({ text: "列出文件失败" }, { status: response.status });
        }

        const { data } = await response.json();
        return NextResponse.json(data, { status: 200 });
      } catch (error) {
        console.log(error, "列出文件失败");
        return NextResponse.json({ text: "服务器内部错误" }, { status: 500 });
      }
    }

全屏模式 退出全屏

  • 图片代理服务 (/api/proxy/route.ts):

作为一个代理服务器,从外部来源抓取图片,确保用户可以轻松访问和下载图片。

    import { NextResponse } from 'next/server';

    export async function GET(request: Request) {
      const { searchParams } = new URL(request.url);
      const imageUrl = searchParams.get('url'); // 获取URL参数

      if (!imageUrl) {
        return NextResponse.json({ error: '请提供图像的URL' }, { status: 400 });
      }

      try {
        const response = await fetch(imageUrl);

        if (!response.ok) {
          return NextResponse.json({ error: '无法加载图像' }, { status: response.status });
        }

        const contentType = response.headers.get('content-type') || 'application/octet-stream';
        const imageBuffer = await response.arrayBuffer();

        return new NextResponse(imageBuffer, {
          headers: {
            'Content-Type': contentType,
            'Content-Disposition': 'attachment; filename="downloaded_image"',
          },
        });
      } catch (error) {
        console.error('在获取图像时发生错误:', error);
        return NextResponse.json({ error: '获取图像失败' }, { status: 500 });
      }
    }

点击这里进入全屏模式,再次点击退出全屏模式

  • 生成签名URL (/api/sign/route.ts)

生成用于上传文件的带有签名的URL。

    import { type NextRequest, NextResponse } from "next/server";
    import { pinata } from "../../../../utils/config";

    export const dynamic = "force-dynamic";

    export async function POST(req: NextRequest) {
      try {
        const data = await req.json();
        const mimeType = data.mime_type;

        let url;

        if (mimeType === 'video/mp4') {
          url = await pinata.gateways.createSignedURL({
            cid: data.cid,
            expires: 7776000,
          })
        } else {
          url = await pinata.gateways.createSignedURL({
            cid: data.cid,
            expires: 7776000,
          }).optimizeImage({
            width: 300,
            height: 300,
            format: "webp",
            fit: "contain",
            quality: 90,
            dpr: 2,
            sharpen: 1,

          });
        }

        return NextResponse.json(url, { status: 200 });
      } catch (error) {
        console.log(error);
        return NextResponse.json({ text: "生成签名URL时出错:" }, { status: 500 });
      }
    }

全屏 退出全屏

该应用程序是由以下技术构建的。请提供具体的技术信息,以便翻译。

  • Pinata:文件API接口

  • 前端 :React,Next.js,Framer Motion

  • 样式设计:采用 Tailwind CSS 来实现美观且响应式的布局。

  • 托管在 Vercel 上:使用 Vercel 进行部署。
最后的结论

婚礼是充满爱、笑声和无数难忘瞬间的欢乐时刻。捕捉这些珍贵的回忆非常重要,而有了这款 [婚礼记忆]() 应用,现在变得比以前更加简单!

这款应用允许每位客人在活动当天拍下美好瞬间并轻松分享,确保不放过任何瞬间,让每个人都能访问庆祝活动的共同记忆。

该应用程序利用Pinata的文件API的功能,让宾客可以安全高效地上传和分享他们的照片和视频,共同创建一个完美记录这一天美好时光的相册。

了解该应用如何与Pinata集成及功能详情,请参见Pinata的文档

谢谢。

此处省略


0人推荐
随时随地看视频
慕课网APP