Skip to content
This repository has been archived by the owner on Jun 15, 2022. It is now read-only.

Commit

Permalink
Trash bin
Browse files Browse the repository at this point in the history
  • Loading branch information
moughxyz committed Jan 11, 2019
1 parent f3ebdd0 commit 56b452a
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 85 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -28,7 +28,7 @@
"react-navigation": "^3.0.9",
"react-navigation-header-buttons": "^2.1.1",
"regenerator": "^0.13.3",
"sn-models": "0.1.8",
"sn-models": "0.1.11",
"standard-file-js": "0.3.31"
},
"devDependencies": {
Expand Down
63 changes: 48 additions & 15 deletions src/lib/itemActionManager.js
Expand Up @@ -8,6 +8,10 @@ export default class ItemActionManager {

static DeleteEvent = "DeleteEvent";

static TrashEvent = "TrashEvent";

static EmptyTrashEvent = "EmptyTrashEvent";

static PinEvent = "PinEvent";
static UnpinEvent = "UnpinEvent";

Expand All @@ -26,11 +30,40 @@ export default class ItemActionManager {

static handleEvent(event, item, callback, afterConfirmCallback) {

console.log("Handling event", event);
if(event == this.TrashEvent) {
var title = `Move to Trash`;
var message = `Are you sure you want to move this ${item.displayName.toLowerCase()} to the trash?`;

AlertManager.get().confirm({
title: title,
text: message,
confirmButtonText: "Confirm",
onConfirm: () => {
item.content.trashed = true;
item.setDirty(true);
Sync.get().sync();
callback && callback();
}
})
}

else if(event == this.EmptyTrashEvent) {
let deletedCount = ModelManager.get().trashedItems().length;
AlertManager.get().confirm({
title: "Empty Trash",
text: `Are you sure you want to permanently delete ${deletedCount} notes?`,
confirmButtonText: "Delete",
onConfirm: () => {
ModelManager.get().emptyTrash();
Sync.get().sync();
callback && callback();
}
})
}

if(event == this.DeleteEvent) {
else if(event == this.DeleteEvent) {
var title = `Delete ${item.displayName}`;
var message = `Are you sure you want to delete this ${item.displayName.toLowerCase()}?`;
var message = `Are you sure you want to permanently delete this ${item.displayName.toLowerCase()}?`;

AlertManager.get().confirm({
title: title,
Expand All @@ -48,33 +81,33 @@ export default class ItemActionManager {
})
}

else if(event == this.PinEvent || event == this.UnpinEvent) {
else if(event == this.PinEvent || event == this.UnpinEvent) {
item.setAppDataItem("pinned", event == this.PinEvent);
item.setDirty(true);
Sync.get().sync();
callback && callback();
}

else if(event == this.LockEvent || event == this.UnlockEvent) {
item.setAppDataItem("locked", event == this.LockEvent);
item.setDirty(true, true);
Sync.get().sync();
callback && callback();
}
item.setAppDataItem("locked", event == this.LockEvent);
item.setDirty(true, true);
Sync.get().sync();
callback && callback();
}

else if(event == this.ArchiveEvent || event == this.UnarchiveEvent) {
else if(event == this.ArchiveEvent || event == this.UnarchiveEvent) {
item.setAppDataItem("archived", event == this.ArchiveEvent);
item.setDirty(true);
Sync.get().sync();
callback && callback();
}

else if(event == this.ProtectEvent || event == this.UnprotectEvent) {
item.content.protected = !item.content.protected;
item.setDirty(true);
Sync.get().sync();
callback && callback();
}
item.content.protected = !item.content.protected;
item.setDirty(true);
Sync.get().sync();
callback && callback();
}

else if(event == this.ShareEvent) {
ApplicationState.get().performActionWithoutStateChangeImpact(() => {
Expand Down
77 changes: 39 additions & 38 deletions src/lib/sfjs/modelManager.js
Expand Up @@ -11,9 +11,6 @@ SFModelManager.ContentTypeClassMapping = {
"SN|Privileges" : SFPrivileges
};

const SystemSmartTagIdAllNotes = "all-notes";
const SystemSmartTagIdArchivedNotes = "archived-notes";

export default class ModelManager extends SFModelManager {

static instance = null;
Expand Down Expand Up @@ -92,35 +89,15 @@ export default class ModelManager extends SFModelManager {
}

buildSystemSmartTags() {
this.systemSmartTags = [
new SNSmartTag({
uuid: SystemSmartTagIdAllNotes,
content: {
title: "All notes",
isAllTag: true,
predicate: new SFPredicate.fromArray(["content_type", "=", "Note"])
}
}),
new SNSmartTag({
uuid: SystemSmartTagIdArchivedNotes,
content: {
title: "Archived",
isArchiveTag: true,
predicate: new SFPredicate.fromArray(["archived", "=", true])
}
})
]
this.systemSmartTags = SNSmartTag.systemSmartTags();
}

defaultSmartTag() {
return this.systemSmartTags[0];
}

systemSmartTagIds() {
return [
SystemSmartTagIdAllNotes,
SystemSmartTagIdArchivedNotes
]
return this.systemSmartTags.map((tag) => {return tag.uuid});
}

getSmartTagWithId(id) {
Expand All @@ -134,14 +111,34 @@ export default class ModelManager extends SFModelManager {
getSmartTags() {
let userTags = this.validItemsForContentType("SN|SmartTag").sort((a, b) => {
return a.content.title < b.content.title ? -1 : 1;
});;
});
return this.systemSmartTags.concat(userTags);
}

notesMatchingPredicate(predicate) {
let notePredicate = ["content_type", "=", "Note"];
// itemsMatchingPredicate can return non-note types
return this.itemsMatchingPredicates([notePredicate, predicate]);

trashSmartTag() {
return this.systemSmartTags.find((tag) => tag.content.isTrashTag);
}

trashedItems() {
return this.notesMatchingSmartTag(this.trashSmartTag());
}

emptyTrash() {
let notes = this.trashedItems();
for(let note of notes) {
this.setItemToBeDeleted(note);
}
}

notesMatchingSmartTag(tag) {
let contentTypePredicate = new SFPredicate("content_type", "=", "Note");
let predicates = [contentTypePredicate, tag.content.predicate];
if(!tag.content.isTrashTag) {
let notTrashedPredicate = new SFPredicate("content.trashed", "=", false);
predicates.push(notTrashedPredicate);
}
return this.itemsMatchingPredicates(predicates);
}

getNotes(options = {}) {
Expand All @@ -151,7 +148,7 @@ export default class ModelManager extends SFModelManager {
if(selectedTagIds && selectedTagIds.length > 0) {
selectedSmartTag = selectedTagIds.length == 1 && this.getSmartTagWithId(selectedTagIds[0]);
if(selectedSmartTag) {
notes = this.notesMatchingPredicate(selectedSmartTag.content.predicate);
notes = this.notesMatchingSmartTag(selectedSmartTag);
} else {
tags = ModelManager.get().findItems(options.selectedTagIds);
if(tags.length > 0) {
Expand Down Expand Up @@ -184,14 +181,18 @@ export default class ModelManager extends SFModelManager {
return false;
}

// If we're not dealing with the system archived tag, then we only want to
// filter for this note if it's not archived. (Hide archived if not archive tag)
let isExplicitlyArchiveTag = selectedSmartTag && selectedSmartTag.content.isArchiveTag;
if(!isExplicitlyArchiveTag) {
return !note.archived;
} else {
return note.archived;
let isTrash = selectedSmartTag && selectedSmartTag.content.isTrashTag;
let canShowArchived = (selectedSmartTag && selectedSmartTag.content.isArchiveTag) || isTrash;

if(!isTrash && note.content.trashed) {
return false;
}

if(note.archived && !canShowArchived) {
return false;
}

return true;
})

let sortValueFn = (a, b, pinCheck = false) => {
Expand Down
29 changes: 21 additions & 8 deletions src/screens/Notes/NoteCell.js
Expand Up @@ -81,16 +81,22 @@ export default class NoteCell extends ThemedPureComponent {
}
});
} else {
let options = [
ActionSheetWrapper.BuildOption({text: pinLabel, key: pinEvent, callback: callbackForOption}),
ActionSheetWrapper.BuildOption({text: archiveLabel, key: archiveEvent, callback: callbackForOption}),
ActionSheetWrapper.BuildOption({text: lockLabel, key: lockEvent, callback: callbackForOption}),
ActionSheetWrapper.BuildOption({text: protectLabel, key: protectEvent, callback: callbackForOption}),
ActionSheetWrapper.BuildOption({text: "Share", key: ItemActionManager.ShareEvent, callback: callbackForOption}),
]

if(!this.props.item.content.trashed) {
options.push(ActionSheetWrapper.BuildOption({text: "Move to Trash", key: ItemActionManager.TrashEvent, destructive: true, callback: callbackForOption}));
}

sheet = new ActionSheetWrapper({
title: this.props.item.safeTitle(),
options: [
ActionSheetWrapper.BuildOption({text: pinLabel, key: pinEvent, callback: callbackForOption}),
ActionSheetWrapper.BuildOption({text: archiveLabel, key: archiveEvent, callback: callbackForOption}),
ActionSheetWrapper.BuildOption({text: lockLabel, key: lockEvent, callback: callbackForOption}),
ActionSheetWrapper.BuildOption({text: protectLabel, key: protectEvent, callback: callbackForOption}),
ActionSheetWrapper.BuildOption({text: "Share", key: ItemActionManager.ShareEvent, callback: callbackForOption}),
ActionSheetWrapper.BuildOption({text: "Delete", key: ItemActionManager.DeleteEvent, destructive: true, callback: callbackForOption}),
], onCancel: () => {
options: options,
onCancel: () => {
this.setState({actionSheet: null});
}
});
Expand Down Expand Up @@ -131,6 +137,13 @@ export default class NoteCell extends ThemedPureComponent {
})
}

if(note.content.trashed) {
flags.push({
text: "Deleted",
color: StyleKit.variables.stylekitDangerColor
})
}

return flags;
}

Expand Down

0 comments on commit 56b452a

Please sign in to comment.