亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

Pixxsha分享你的時刻,按你喜歡的方式

这是对Pinaata挑战的投稿。

Pixxsha - 以你的方式分享你的瞬间

Pixxsha 是一个照片分享平台,帮助您安全地保存和分享珍贵的记忆。来自 DEV.to 和 Pinata 挑战,Pixxsha 希望改善我们保存和分享时刻的方法。

Pixxsha有什么特别之处?
  • 安全储存:你的照片将被储存在星际文件系统(IPFS)上,确保它们既安全又随时可访问。

  • 智能灵活的分享:您可以根据需要公开、私密或限时分享照片,一切由您说了算。
    /public:通过一个简单的链接,您可以和任何人分享您的照片。
    /restricted:通过添加特定人员来控制谁能访问,让您更加安心。
    /view Once:发送一个查看后即消失的链接。

  • 您可以为照片创建一些分组,比如“我的21岁生日”或者“宝宝的第一年”。

点击登录 Pixxsha 😎
pixxsha

Pixxsha 的未来会是怎样的?

我们才刚刚开始呢!这里有一些我们正在努力实现的超棒功能。

🌟 生命时光线:用照片分组为重要的时刻制作一个视觉生命旅程。

👨‍👩‍👧‍👦 家庭相册:为家庭回忆设立的专属空间,比如“宝宝的第一步学走”或“家庭旅行”。

🤝 协作群组:与家人和朋友分享并贡献照片到相册。

zh:

谢谢亲爱的DEV社区成员们和Pinata团队!

这个挑战激发了我们创建Pixxsha的灵感,我们很期待看到Pixxsha未来的发展方向。我们很感激有机会创造一些能够改变人们珍藏回忆方式的东西。

示例

Pixxsha 的控制面板

仪表盘

我们的代码

这个GitHub项目主页

更多关于如何集成Pinata的细节

派对帽和IPFS

我们已经把 Pinata 的 Web3 SDK 集成到我们的 IPFS 交互中。这里展示一下我们是怎么用它的。

  • 来自 pinataService.ts 文件
    import { PinataSDK } from 'pinata-web3';

    const pinata = new PinataSDK({
      pinataJwt: process.env.PINATA_JWT!,
      pinataGateway: process.env.PINATA_GATEWAY!,
    });

    // 将文件上传到 Pinata,可选包含标签和分组分配
    export const uploadFile = async (file: File, tags: Record<string, string>, groupId?: string) => {
      try {
        const upload = await pinata.upload.file(file, {
          metadata: {
            name: file.name,
            keyvalues: tags,
          },
        });

        if (groupId) {
          await pinata.groups.addCids({
            groupId,
            cids: [upload.IpfsHash],
          });
        }

        return upload;
      } catch (error) {
        throw new Error(`上传文件失败: ${error.message}`);
      }
    };

    // 使用 IPFS 哈希从 Pinata 获取文件内容
    export const retrieveFile = async (ipfsHash: string) => {
      try {
        const data = await pinata.gateways.get(ipfsHash);
        return data;
      } catch (error) {
        throw new Error(`获取文件失败: ${error.message}`);
      }
    };

    // 通过 ID 获取组的详细信息
    export const getGroup = async (groupId: string) => {
      try {
        return await pinata.groups.get({ groupId });
      } catch (error) {
        throw new Error(`获取组失败: ${error.message}`);
      }
    };

    // 在 Pinata 中创建新的组
    export const createGroup = async (name: string) => {
      try {
        return await pinata.groups.create({ name });
      } catch (error) {
        throw new Error(`创建组失败: ${error.message}`);
      }
    };

    // 列出所有组,可选按名称、偏移量和限制进行过滤
    export const listGroups = async (name?: string, offset?: number, limit?: number) => {
      try {
        const query = pinata.groups.list();
        if (name) query.name(name);
        if (offset) query.offset(offset);
        if (limit) query.limit(limit);
        return await query;
      } catch (error) {
        throw new Error(`列出组失败: ${error.message}`);
      }
    };

    // 更新组名
    export const updateGroup = async (groupId: string, name: string) => {
      try {
        return await pinata.groups.update({ groupId, name });
      } catch (error) {
        throw new Error(`更新组失败: ${error.message}`);
      }
    };

    // 通过 ID 删除组信息
    export const deleteGroup = async (groupId: string) => {
      try {
        await pinata.groups.delete({ groupId });
      } catch (error) {
        throw new Error(`删除组失败: ${error.message}`);
      }
    };

    // 将 CID 从组中移除
    export const removeCidsFromGroup = async (groupId: string, cids: string[]) => {
      try {
        await pinata.groups.removeCids({ groupId, cids });
      } catch (error) {
        throw new Error(`从组中移除 CID 失败: ${error.message}`);
      }
    };

    // 将 CID 添加到组
    export const addCidsToGroup = async (groupId: string, cids: string[]) => {
      try {
        await pinata.groups.addCids({ groupId, cids });
      } catch (error) {
        throw new Error(`将 CID 添加到组失败: ${error.message}`);
      }
    };

进入全屏模式 退出全屏

  • 在我们的 photoController.ts 中,我们是如何处理照片分享的。
    export const sharePhoto = async (req: Request, res: Response) => {
        const { photoId, shareType, recipientEmails } = req.body;

        try {
          const { data: photo, error } = await supabase
            .from('photos')
            .select('*')
            .eq('id', photoId)
            .single();

          if (error) throw error;

          if (photo.user_id !== (req as any).user.userId) {
            return res.status(403).json({ error: '您无权分享此照片' });
          }

          const shareLink = `${config.pinataGateway}/ipfs/${photo.ipfs_hash}`;

          let expirationDate = null;
          let viewCount = null;

          switch (shareType) {
            case 'public':
              break;
            case 'restricted':
              if (!recipientEmails || recipientEmails.length === 0) {
                return res.status(400).json({ error: '未指定收件人邮箱' });
              }
              break;
            case 'view-once':
              viewCount = 1;
              break;
            case 'time-limited':
              expirationDate = new Date(Date.now() + 24 * 60 * 60 * 1000); // 即24小时后过期
              break;
            default:
              return res.status(400).json({ error: '无效的分享方式' });
          }

          const { data: share, error: shareError } = await supabase
            .from('shares')
            .insert({
              photo_id: photoId,
              share_type: shareType,
              share_link: shareLink,
              recipient_emails: recipientEmails,
              expiration_date: expirationDate,
              view_count: viewCount,
              remaining_views: viewCount,
            });

          if (shareError) throw shareError;

          res.json({ shareLink, share });
        } catch (error: any) {
          res.status(500).json({ error: error.message });
        }
      };

全屏模式,退出全屏

  • 使用 Pinata 来整理照片
export const addCidsToGroup = async (groupId: string, cids: string[]) => {
  // 此函数将CIDs添加到组中。
  return await pinata.groups.addCids({ groupId, cids });
};

切换到全屏模式 退出全屏

这允许用户将他们的照片整理成自定义相册,比如“2023年假期照”或“家庭合影”。

  • 集成仪表板 我们创建了一个仪表板,它利用了 Pinata 的组和文件管理,:
    export const 获取仪表板数据 = async (req: Request, res: Response) => {
      // 获取带有标签和组的照片
      const { data: photos } = await supabase
        .from('photos')
        .select(`*, 标签 (标签名), 组 (组名)`)
        .eq('user_id', userId);

      // ... 聚合数据以供仪表板使用
      res.json({ photos, photoCount, recentUploads });
    };

全屏。退出全屏。

下一步会是什么呢?

我们正在继续开发Pixxsha,更注重用户体验的提升并增添更多功能。请关注我们的更新消息,欢迎随时联系我们!如果您想加入我们的旅程,请随时联系我们!

zh: ……

团队小伙伴

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消