神马笔记 版本1.8.0——删除笔记/文件夹·代码篇

神马笔记 版本1.8.0——删除笔记/文件夹·代码篇

一、目标

完成神马笔记管理功能的最后一块拼图——删除文件/文件夹。

二、体验地址

神马笔记最新版本下载:【神马笔记 版本1.8.0——删除笔记/文件夹功能.apk

三、功能设计

1. 实现删除功能

删除功能包括以下几个操作

  1. 删除到最近删除
  2. 最近删除恢复到原来位置
  3. 最近删除彻底删除笔记/文件夹

删除及恢复操作,实际上是一个移动操作。只是移动到最近删除,或者从最近删除移动到原来位置。

彻底删除操作则将数据从数据记录中移除,并且删除相关的文件。

2. 处理最近删除的可见性

另外需要处理的一个问题时当笔记/文件夹位于最近删除时,是否可见?

位置 最近删除是否可见?
搜索 是。搜索结果包括最近删除的笔记/文件夹。
我的笔记 否。已经移动到最近删除
最近项目 否。
最近删除 是。只显示删除的笔记/文件夹。
标签 否。
个人收藏 否。隐藏位于最近删除的文件夹,恢复后重新显示。

四、实现过程

1. 删除到最近删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public boolean trash() {
if (this.isTrash()) {
return false;
}

if (entry == null) {
return false;
}

String parentId = ROOT_TRASH;
if (this.getParent().equals(parentId)) {
return false;
}

// set deleted now
this.setDeleted(DateTime.now());

// set name
String name = RecordUtils.getName(context, entry, parentId, true);
if (this.isAlias()) {
entry.setAlias(name);
} else {
entry.setName(name);
}

// set ancestor for recover
entry.setAncestor(entry.getParent());

// set parent
entry.setParent(parentId);

return true;
}
  1. 最近删除中寻找新的名字,避免重名
  2. 记录原来的位置,以进行恢复操作
  3. 设置新的位置——最近删除

2. 从最近删除恢复

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public boolean recover() {
if (!this.isTrash()) {
return true;
}

if (entry == null) {
return true;
}

String parentId = entry.getAncestor().orElse("");

// check parent exist or not
if (!TextUtils.isEmpty(parentId)) {
if (!parentId.equals(ROOT_NOTE)) {
RecordEntity parent = RecordEntity.create(parentId).orElse(null);
parentId = (parent == null || parent.isTrash())? "": parent.getId();
}
}

// if parent is not exist, we move record to root
if (TextUtils.isEmpty(parentId)) {
parentId = ROOT_NOTE;
}

// set deleted null
this.setDeleted(null);

// set name
String name = RecordUtils.getName(context, entry, parentId, true);
if (this.isAlias()) {
entry.setAlias(name);
} else {
entry.setName(name);
}

// set ancestor null
entry.setAncestor(null);

// set parent
entry.setParent(parentId);

return true;

}
  1. 检查原来的位置是否存在,并且不是位于最近删除
  2. 寻找新的名字,避免恢复时重名
  3. 清空恢复位置,设置回原来位置

3. 彻底删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public List<RecordEntity> delete() {
final RecordTable table = getManager().obtainTable(RecordTable.class);
if (!this.isDirectory()) {

// remove data
table.remove(this.entry);

// to entity
return Arrays.asList(this);

} else {

// filter descendant of this
final String parentId = this.getId();
List<RecordEntry> list = table.getList().stream()
.filter(e -> RecordUtils.isDescendantOf(table, e, parentId))
.collect(Collectors.toList());

// remove data
for (RecordEntry e : list) {
table.remove(e);
}

// to entity
return list.stream()
.map(e -> new RecordEntity(getContext(), e.getId(), e))
.collect(Collectors.toList());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
final void executeDelete(RecordEntity entity) {

// delete from record database
final List<RecordEntity> list = entity.delete();

// delete database entry
{
FavoriteEntity favorite = FavoriteEntity.obtain();

for (RecordEntity e : list) {
String id = e.getId();

if (e.isDirectory()) {

// delete favorite
favorite.delete(id);

} else {

// delete recent
RecentEntity.delete(id);

// delete saved state
SavedStateEntity.delete(id);

// delete image
ImageEntity.deleteByDocument(id);
}

}
}

// delete file system files
for (RecordEntity e : list) {
if (e.isDirectory()) {
continue;
}

CompletableFuture.runAsync(() -> {
try {
// delete snapshot
File file = e.getSnapshot();
if (file.exists()) {
FileUtils.forceDelete(file);
}

// delete note document
file = e.getFile();
if (file.exists()) {
FileUtils.forceDelete(file);
}
} catch (IOException e1) {

}
});
}
}

删除文件夹时,需要删除包含的子文件夹和笔记。

我们通过遍历所有笔记数据,判断是否是当前文件夹的后代来决定是否删除。

最后返回需要删除的笔记/文件夹列表。

彻底删除需要删除以下相关数据。

  1. 笔记记录
  2. 个人收藏,仅文件夹
  3. 最近项目,仅笔记
  4. 笔记状态,仅笔记
  5. 图片记录,仅笔记

另外,还需要删除笔记相关的文件。

  1. 笔记截图
  2. 笔记文件夹

4. 处理文件夹收藏

1
2
3
4
5
public EntityList toList() {
return new EntityList(new FavoriteEntity(this).getList().stream()
.filter(e -> !e.isTrash())
.collect(Collectors.toList()));
}

当文件夹收藏位于最近删除时,隐藏显示,恢复后重新显示。

增加一个过滤接口,只显示非最近删除文件夹。

五、Finally

~撩乱春愁如柳絮~悠悠梦里无寻处~