应用程序对象正在关闭_在IPFS上构建零依赖性的应用程序

本文由IPFS原力区收集译制,版权所属原作者

注:本文由两部分组成。第一部分侧重于身份验证,第二部分侧重于从IPFS发布和获取内容。

36257230e34ad3a60c90e30bf612f674.png

在本教程的上卷中,我们为应用程序设置了身份验证。我们这样做不需要依赖关系,只有两个文件 - index.html和main.js。

在此下卷中,我们将构建这个应用程序,这是一个简单的笔记应用程序,内容存储在IPFS上。我们使用SimpleID的API,IPFS存储通过Pinata提供的服务实现。

这里从html开始。我们已经有了一个部分来保存应用程序内容。找到如下所示的部分:

62df492f1f17282b7a1d31c24c090ddc.png

注销按钮可以保留,但我们需要删除This is the app文本并将其替换为实际应用程序内容。我需要考虑以下几件事情:

  • 如何在记录笔记和查看所有现有笔记之间切换?
  • 如何呈现所有现有笔记?

让我们设置我们的html内容,以支持这些问题的正确答案:

bf3be9ef82562d33eba810d11ef8a378.png

显示应用程序内容时,我们不希望同时显示笔记记录和笔记簿。我们认为显示用户的笔记簿更清晰,然后按一下按钮或其他东西,就会呈现笔记部分。所以,我们从notes-collection渲染和single-note隐藏开始。

你可以注意到在笔记簿中,已经包含了一个没有任何子元素li的ul。那是因为我们将在加载笔记集时以编程方式呈现这些列表项。

现在我们已经拥有了应用程序内容的框架,让我们跳转到JavaScript文件中,并获取notes-collection索引文件。

该文件将包含我们所有笔记的标识符,标题和日期数组。在main.js中,我们首先需要在文件的顶部添加一个新的全局变量。在loading变量下面添加let notesCollection = ;。现在,添加一个名为fetchCollection的新函数:

da48021802164ae611a8f1e16cf2fadd.png

如果您还记得的话,我们创建了一个可重复使用的函数来发布到SimpleID API,该API总是返回一个promise。

这里我们只是指定要发布的url和要包含的数据。我们发送的数据必须包含一个标识符,用于从IPFS网络中查找正确的文件。那就是notesId。

您可能会问,在为每个用户返回正确内容的同时,如何将该标识符用于多个用户。这就是username变量的来源。在我们发布的数据中,用户名应该是您登录用户的用户名。请记住,它存储在localStorage中,我们可以轻松获取并包含它。

当我们向API发出请求时,我们需要考虑可能出现的任何错误,包括之前存储的内容不足。因此,我们需要检查错误,如果没有,则使用响应设置notesCollection数组。否则,我们将notescollection设置为空数组。

但这还不够。我们需要依次通过该数组,并为notes-collection-itemsul 之间的每个笔记符添加一个列表项。我们可以这样做来检查是否会产生错误。所以,如果block在notescollection=json.parse(pinnedcontent)下面添加这个,让我们添加对rendercollection函数的调用。然后我们可以创建renderCollection函数,如下所示:

245953abb28733db774c8f5952116b60.png

这里我们只是抓取我们创建的ul,在它下面创建子列表项,并用注释标题和注释日期填充这些列表项。我们还将注释的id设置为元素id。当我们想要显示笔记的实际内容时,这些将会派上用场。

这需要在用户登录和注册后调用,所以让我们将其连接起来:

7ca6fa3b6fd0a6dd8d3193573e9fbd85.png

我们还需要在每次页面加载时调用fetchcollection,因为用户可能会刷新屏幕。我们应该只在用户登录时才这样做。所以,在main.js顶部的pageload调用下面添加以下内容:

现在,我们已经知道还有没显示的内容,所以让我们考虑一下如何创建新笔记。我之前提到创建一个按钮,我有点喜欢这个想法。让我们在应用程序内容中添加一些内容:

7d4038d9aae0d4f068a2218ae13ad210.png

我们添加了一个按钮,让我们创建新笔记,然后我们将一个事件处理程序绑定到调用它newNote。我们添加了一个按钮来关闭打开的note屏幕。它调用一个函数来关闭note屏幕。

我们还向单个note部分添加了一个工具栏。这将是一个简单的笔记应用程序与简单的功能-粗体,斜体,下划线。我们的工具栏中还有一个保存按钮,稍后我们将把它连接起来。

我们需要给笔记一个标题,所以我们还添加了一个标题输入字段。最后,我们添加了一个contentteditable div来保存注释,并为其提供了一个id,以便稍后引用。

接下来,我想我们应该让New Note按钮显示我们的新笔记,我们在main.js文件中这样做。打开它并添加一个名为newNote的函数:

42d9cb20938c57773504e4aaeda6d328.png

在newNote函数中我们隐藏了笔记簿,因为在编写新笔记时我们不需要看到它。然后我们将显示笔记屏幕。我们还将笔记标题和笔记内容设置为空字符串,因为每次按下New Note时,它应该是一个填充内容的新笔记。

在这里,我们还可以设置closenote函数:

我们正在隐藏笔记记录屏幕并再次显示笔记集屏幕。

需要注意的是,只有当用户单击Save note时才会保存笔记。我们还没有设置好,但是会实现的。这意味着,当用户单击close按钮时,没有保存任何内容。欢迎您以不同的方式设置。

接下来要做的两件事是处理笔记记录部分中的内容更改(当用户记录时,我们希望跟踪这些更改)和处理工具栏按钮。让我们从跟踪内容更改开始。为此,我们将向我们的main.js文件添加一个事件监听器。你可以在第一个函数上面这样做,但在pageLoad调用之下执行此操作,如下所示:

保存,然后在登录到您的应用程序时,继续创建一个新笔记并输入内容。打开开发人员控制台,您应该看到显示您所输入的内容。我们需要跟踪实际内容,以便在保存时,我们有一个变量可供使用。为此,让我们在notescollection变量下面的main.js文件顶部创建一个新的全局变量:

let noteContent =“”;

现在,在事件监听器中,我们可以删除console.log并将其替换为contentEditable div的innerHTML,并将其设置为等于noteContent变量。如下所示:

b89b8c4b1a7b57ba4893a15b10b8e3ab.png

我在下面添加了一个console.log,以确保一切正常。如果需要,可以这样做,并通过创建新注释,输入内容然后打开开发人员控制台来测试。然后您应该会在控制台中看到您输入的内容的html表示形式。

现在,让我们将这个文本格式化。对于我们的工具栏,我们需要为每个项目添加onclick事件处理程序。单击每个工具栏按钮时,它应该适用于应用指定的格式。值得庆幸的是,有一些内置的JavaScript支持这一点。让我们试一试:

48d17d04e9d91a13a83976fae0a94b49.png

我们在JavaScript中使用内置的execCommand功能为我们的笔记应用程序构建一个非常简单的WYSIWYG编辑器。很酷,对吧?你会注意到onmousedown事件处理程序。这是因为当您单击工具栏按钮时,焦点将从需要格式化的文本中删除,从而使按钮看起来无法工作。我们用这个事件处理程序来防止这种情况。

现在,我们需要连接Save Note按钮。让我们考虑一下都需要做什么:

  • 创建一个对象来保存笔记标题、笔记内容和笔记id(可以很容易地生成)
  • 将新注释添加到现有notesCollection数组
  • 保存一个包含所有notesCollection数组的索引文件
  • 保存包含完整内容的note文件本身

让我们在工具栏中的Save Note按钮中添加一个事件处理程序:

537b4819d51613ae75f02f467a703a1f.png

好的,现在,让我们在main.js文件中创建这个函数:

0d8efd11adec59028ffd8153b2f361f9.png

我们正在采取措施确保工作顺利进行,但请继续测试。重新创建笔记,写一些东西,给它一个标题,然后保存它。在控制台中,您应该看到单独注释,并且应该看到notescollection数组已更新。您会注意到note对象不包含内容。这是因为我们要做的第一件事是更新notes的索引,这只需要基本的元数据。

我们要做的下一件事是将索引文件保存到IPFS。没错,你应该一直在等这个。我们保存一些内容!

为了测试这个,让我们更新savenote函数:

6dbc1675ae8026655a7ceed67f3c502b.png

在这里,我们指定API端点,获取登录用户的用户名,对内容进行URIE编码,然后构建一个与数据兼容的数据字符串。这些都被发送到posttoapi函数。我们检查该API调用的响应并查找错误。如果没有错误,我们就准备继续前进。如果有,我们控制台会记录它。

现在,我们才只做了一半。我们还需要保存单个笔记及其内容。让我们来设置一下。在if(!postedContent.indludes("ERROR")块内部,让我们添加:

基本上,我们所做的与保存note collection索引文件时所做的完全相同,但我们是为单个笔记做的。看看我们如何将noteContent变量添加到note对象中?这是因为对于单个笔记,我们还希望加载完整的笔记,包括内容。

如果一切顺利,我们将关闭笔记记录并显示笔记集,但我们也将调用rendercollection以确保用新的笔记更新ui。现在是对renderCollection函数进行一些更新,我们可以这样做:

4100e4f42691a00c5eb75c6208a7f5b3.png

我们在笔记列表项中添加了一个样式属性,这样当我们将鼠标悬停在它上面时,鼠标光标会变成一个指针,就像悬停在链接上一样。我们还添加了一个事件监听器,该侦听器在单击时调用loadnote函数。这非常直观,但我们希望能够点击一个笔记的标题并加载单击的笔记的全部内容。

现在让我们去掉loadNote函数:

让我们继续进行测试。如果保存并刷新浏览器,则应该看到(如果已保存了任何笔记),保存的笔记列表将以无序列表的形式显示。单击其中一个笔记的标题并检查开发人员控制台。您应该看到显示这条笔记的ID。

我们快要完成了。我们现在需要做的就是加载带有实际内容的笔记,以便用户可以根据需要查看或编辑。让我们在loadNote函数中完成这些操作:

13b5a07dcd18f1ab93c1f97cfb6a11c5.png

现在测试一下。创建一个笔记,保存,打开它。一切似乎都正常运行,但我们忘记了一件事。如果我们要编辑现有笔记,它不会更新笔记,而是创建新的笔记。我们来解决这个问题。

首先,我们需要确保将单个笔记id设置为全局变量,以便在尝试保存更新的笔记时再次使用它。因此,在main.js文件的顶部,添加以下全局变量noteContent = "":

let singleNoteId = null;

然后,在您的loadNote函数中,在开头添加:

singleNoteId = id;

现在,转到saveNote函数,用下面的代码更新该函数的顶部:

a5a35de0e9bed5786950250989a3b423.png

现在,我们应该可以创建新笔记并更新现有笔记。让我们确认一下。打开现有笔记,编辑它,然后单击“保存”按钮。

你做到了!您刚刚构建了一个零依赖关系应用程序,您可以执行以下操作:

  • 注册
  • 登录
  • 注销
  • 新建笔记
  • 格式说明
  • 保存到IPFS
  • 从IPFS获取

除了这是一个零依赖应用程序之外,应用程序的整个还非常小,非捆绑和未分解和解压缩不到20kb。

整个应用程序非常难看,我提供的CSS没办法让它变得更好,但你可以抓取这个CSS,使它至少看起来像样。

在本教程中值得指出的是,您正在使用API密钥客户端。这并不安全。如果您担心其他人看到并使用您的API密钥,那么应该通过建立服务器、调用该服务器以及在该服务器上使用SimpleIDAPI函数来掩盖这一点。您可以在服务器端保护密钥。

—end—

本文由IPFS原力区编译,原文链接:

https://medium.com/simpleid-dev-tools/tutorial-build-an-encrypted-notes-app-on-ipfs-part-ii-3bdba2d867ad

【IPFS原力区】总部位于上海,聚集基于分布式网络&存储的众多技术大咖和爱好者,深耕基于 IPFS 的商业生态建设和社区发展。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值