diff --git a/package-lock.json b/package-lock.json
index fb7d488..1732c78 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,7 +18,9 @@
"build-url": "^6.0.1",
"docx": "^7.7.0",
"dragselect": "^2.5.5",
+ "fast-sort": "^3.2.1",
"file-saver": "^2.0.5",
+ "hash-sum": "^2.0.0",
"idb-keyval": "^6.2.0",
"is-valid-http-url": "^1.0.3",
"jsdom": "^20.0.3",
@@ -2225,6 +2227,11 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
},
+ "node_modules/fast-sort": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/fast-sort/-/fast-sort-3.2.1.tgz",
+ "integrity": "sha512-ECGwVH57yCv3C8v+4BQkQf65bNR4nFetxfGRRLYmzFEAK3oZBr7zCakBjOY/AptmmoU3ffMPJLLN1rdKdMHoUA=="
+ },
"node_modules/fastq": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
@@ -2450,6 +2457,11 @@
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
},
+ "node_modules/hash-sum": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz",
+ "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg=="
+ },
"node_modules/html-encoding-sniffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
@@ -5952,6 +5964,11 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
},
+ "fast-sort": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/fast-sort/-/fast-sort-3.2.1.tgz",
+ "integrity": "sha512-ECGwVH57yCv3C8v+4BQkQf65bNR4nFetxfGRRLYmzFEAK3oZBr7zCakBjOY/AptmmoU3ffMPJLLN1rdKdMHoUA=="
+ },
"fastq": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
@@ -6116,6 +6133,11 @@
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
},
+ "hash-sum": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz",
+ "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg=="
+ },
"html-encoding-sniffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
diff --git a/package.json b/package.json
index 0446166..52f9247 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,9 @@
"build-url": "^6.0.1",
"docx": "^7.7.0",
"dragselect": "^2.5.5",
+ "fast-sort": "^3.2.1",
"file-saver": "^2.0.5",
+ "hash-sum": "^2.0.0",
"idb-keyval": "^6.2.0",
"is-valid-http-url": "^1.0.3",
"jsdom": "^20.0.3",
diff --git a/src/lib/components/xp/Previewable.svelte b/src/lib/components/xp/Previewable.svelte
index 8cf26f6..9f4392c 100644
--- a/src/lib/components/xp/Previewable.svelte
+++ b/src/lib/components/xp/Previewable.svelte
@@ -28,6 +28,7 @@
};
async function load_preview(){
+ console.log(preview_url)
if(preview_url != null) return;
if(fs_id == null) return;
let url = await fs.get_url(fs_id);
diff --git a/src/lib/components/xp/Viewer2.svelte b/src/lib/components/xp/Viewer2.svelte
index 1447035..3a7ff37 100644
--- a/src/lib/components/xp/Viewer2.svelte
+++ b/src/lib/components/xp/Viewer2.svelte
@@ -158,7 +158,7 @@
- {#each items as item}
+ {#each items as item (item.id)}
open(item.id)}
diff --git a/src/lib/components/xp/Viewer3.svelte b/src/lib/components/xp/Viewer3.svelte
index 1d693e4..26eb9c3 100644
--- a/src/lib/components/xp/Viewer3.svelte
+++ b/src/lib/components/xp/Viewer3.svelte
@@ -128,7 +128,7 @@
- {#each items as item}
+ {#each items as item (item.id)}
open(item.id)}>
diff --git a/src/routes/xp/desktop_folder.svelte b/src/routes/xp/desktop_folder.svelte
index 38b7b62..ae4b2aa 100644
--- a/src/routes/xp/desktop_folder.svelte
+++ b/src/routes/xp/desktop_folder.svelte
@@ -231,7 +231,7 @@
- {#each items as item, index}
+ {#each items as item, index (item.id)}
open(item.id)} on:contextmenu={(e) => on_rightclick(e, item)}
diff --git a/src/routes/xp/programs/my_computer/sort.js b/src/routes/xp/programs/my_computer/sort.js
new file mode 100644
index 0000000..8eb63fc
--- /dev/null
+++ b/src/routes/xp/programs/my_computer/sort.js
@@ -0,0 +1,58 @@
+import { sort } from 'fast-sort';
+import { SortOptions, SortOrders } from '../../../../lib/system';
+
+let cache = {};
+onmessage = async ({data}) => {
+ let {type, hash, id, items, sort_option, sort_order} = data;
+
+ if(type != 'sort') return;
+ if(sort_option == SortOptions.NONE){
+ postMessage({id, sorted_items: items, type: 'sorted'});
+ return;
+ }
+
+ if(cache[hash] != null){
+ postMessage({id, sorted_items: cache[hash], type: 'sorted'});
+ return;
+ }
+
+ console.log('sorting', hash);
+
+ for(let item of items){
+ if(item.type == 'folder'){
+ item.size = 0;
+ }
+ }
+ let order_key = sort_order == SortOrders.ASCENDING ? 'asc' : 'desc';
+ let option_key = 'name';
+
+ switch (sort_option) {
+ case SortOptions.NAME:
+ option_key = 'name';
+ break;
+ case SortOptions.SIZE:
+ option_key = 'size';
+ break;
+ case SortOptions.DATE_CREATED:
+ option_key = 'date_created';
+ break;
+ case SortOptions.DATE_MODIFIED:
+ option_key = 'date_modified';
+ break;
+ default:
+ break;
+ }
+
+ let predicate = {};
+ predicate[order_key] = elm => {
+ if(option_key == 'name'){
+ return elm[option_key].toLowerCase();
+ } else {
+ return elm[option_key];
+ }
+ }
+
+ let sorted_items = sort(items).by([predicate]);
+
+ postMessage({id, sorted_items, type: 'sorted'})
+}
\ No newline at end of file
diff --git a/src/routes/xp/programs/my_computer/viewer.svelte b/src/routes/xp/programs/my_computer/viewer.svelte
index 8d4fb02..d104cc9 100644
--- a/src/routes/xp/programs/my_computer/viewer.svelte
+++ b/src/routes/xp/programs/my_computer/viewer.svelte
@@ -14,6 +14,7 @@
let dispatch = createEventDispatcher();
import DragSelect from 'dragselect';
import Previewable from '../../../../lib/components/xp/Previewable.svelte';
+ import hash_sum from 'hash-sum';
export let self;
export let my_computer_instance;
@@ -27,6 +28,34 @@
.filter(el => el != null)
.filter(el => !hidden_items.includes(el.id));
+ $: sorted_items = id ? null : null;//reset sorted_items every time id changes
+ let worker = new Worker(new URL('./sort.js', import.meta.url), {type: 'module'});
+ worker.onmessage = ({data}) => {
+ if(data.type == 'sorted' && data.id == id){
+ console.log('update sorted_items', id);
+ sorted_items = data.sorted_items;
+ }
+ }
+
+ let last_sort_tx_hash;
+ $: {
+ if(id){
+ let hash_object = {
+ id,
+ items,
+ sort_option: $hardDrive[id].sort_option,
+ sort_order: $hardDrive[id].sort_order
+ };
+
+ let hash = hash_sum(hash_object);
+ console.log({hash})
+ if(hash != last_sort_tx_hash){
+ last_sort_tx_hash = hash;
+ worker.postMessage({type: 'sort', hash, ...hash_object});
+ }
+ }
+ }
+
$: is_focus = $zIndex == my_computer_instance?.window.z_index;
let computer = my_computer.map(el => $hardDrive[el]);
@@ -257,34 +286,38 @@
on:drop={on_drop} on:dragover={on_drop_over} bind:this={node_ref}>
- {#each items as item}
-
open(item.id)} on:contextmenu={(e) => on_rightclick(e, item)}>
- {#if previewable_exts.includes(item.ext)}
-
- {:else}
-
-
- {/if}
-
- {item.name}
-
- {#if $selectingItems.includes(item.id) && renaming}
-
- {/if}
-
-
- {/each}
+ {#if sorted_items}
+ {#each sorted_items as item (item.id)}
+
open(item.id)} on:contextmenu={(e) => on_rightclick(e, item)}>
+ {#if previewable_exts.includes(item.ext)}
+
+ {:else}
+
+
+ {/if}
+
+ {item.name}
+
+ {#if $selectingItems.includes(item.id) && renaming}
+
+ {/if}
+
+
+ {/each}
+ {:else}
+
working on it...
+ {/if}