Format existing code with new conventions

This commit is contained in:
maxichrome 2022-05-22 23:24:43 -05:00
parent 0b7a7c05d1
commit f5e0666d11
No known key found for this signature in database
GPG key ID: DDC459310E98B6AB
153 changed files with 4983 additions and 4780 deletions

View file

@ -43,7 +43,7 @@ body:
id: info
attributes:
label: Platform and versions
description: "Please include the output of `pnpm --version && cargo --version && rustc --version` along with information about your Operating System such as version and/or specific distribution if revelant."
description: 'Please include the output of `pnpm --version && cargo --version && rustc --version` along with information about your Operating System such as version and/or specific distribution if revelant.'
render: shell
validations:
required: true

View file

@ -1,10 +1,9 @@
<!-- Put any information about this PR up here -->
<!-- Which issue does this PR close? -->
<!-- If this PR does not have a corresponding issue,
make sure one gets created before you create this PR.
You can create a bug report or feature request at
https://github.com/spacedriveapp/spacedrive/issues/new/choose -->
Closes #(issue)

View file

@ -1,9 +1,10 @@
{
"plugins": ["@trivago/prettier-plugin-sort-imports"],
"useTabs": true,
"printWidth": 100,
"singleQuote": true,
"trailingComma": "none",
"jsxBracketSameLine": false,
"bracketSameLine": false,
"semi": true,
"quoteProps": "consistent",
"importOrder": [

View file

@ -1,5 +1,4 @@
hard_tabs = true
tab_spaces = 4
match_block_trailing_comma = true
max_width = 90
newline_style = "Unix"

View file

@ -1,4 +1,3 @@
# Contributor Covenant Code of Conduct
## Our Pledge
@ -18,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
@ -120,14 +119,14 @@ version 2.0, available at
[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
[Mozilla's code of conduct enforcement ladder][mozilla coc].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
[https://www.contributor-covenant.org/faq][faq]. Translations are available
at [https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[mozilla coc]: https://github.com/mozilla/diversity
[faq]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations

View file

@ -61,10 +61,11 @@ If you are having issues ensure you are using the following versions of Rust and
### Pull Request
When you're finished with the changes, create a pull request, also known as a PR.
- Fill the "Ready for review" template so that we can review your PR. This template helps reviewers understand your changes as well as the purpose of your pull request.
- Don't forget to [link PR to issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) if you are solving one.
- Enable the checkbox to [allow maintainer edits](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/allowing-changes-to-a-pull-request-branch-created-from-a-fork) so the branch can be updated for a merge.
Once you submit your PR, a team member will review your proposal. We may ask questions or request for additional information.
Once you submit your PR, a team member will review your proposal. We may ask questions or request for additional information.
- We may ask for changes to be made before a PR can be merged, either using [suggested changes](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request) or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch.
- As you update your PR and apply changes, mark each conversation as [resolved](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request#resolving-conversations).
- If you run into any merge issues, checkout this [git tutorial](https://lab.github.com/githubtraining/managing-merge-conflicts) to help you resolve merge conflicts and other issues.

View file

@ -38,7 +38,6 @@ Organize files across many devices in one place. From cloud services to offline
For independent creatives, hoarders and those that want to own their digital footprint. Spacedrive provides a file management experience like no other, and it's completely free.
<p align="center">
<img src="https://raw.githubusercontent.com/spacedriveapp/.github/main/profile/app.png" alt="Logo">
<br />

View file

@ -1,6 +1,5 @@
max_width = 100
hard_tabs = false
tab_spaces = 2
hard_tabs = true
newline_style = "Auto"
use_small_heuristics = "Default"
reorder_imports = true

View file

@ -1,17 +1,18 @@
import React, { useEffect, useState } from 'react';
import { createRoot } from 'react-dom/client';
// import Spacedrive interface
import SpacedriveInterface, { Platform } from '@sd/interface';
import { listen, Event } from '@tauri-apps/api/event';
// import types from Spacedrive core (TODO: re-export from client would be cleaner)
import { ClientCommand, ClientQuery, CoreEvent } from '@sd/core';
// import Spacedrive JS client
import { BaseTransport } from '@sd/client';
// import types from Spacedrive core (TODO: re-export from client would be cleaner)
import { ClientCommand, ClientQuery, CoreEvent } from '@sd/core';
// import Spacedrive interface
import SpacedriveInterface, { Platform } from '@sd/interface';
// import tauri apis
import { dialog, invoke, os, shell } from '@tauri-apps/api';
import { Event, listen } from '@tauri-apps/api/event';
import { convertFileSrc } from '@tauri-apps/api/tauri';
import '@sd/ui/style';
import { appWindow } from '@tauri-apps/api/window';
import React, { useEffect, useState } from 'react';
import { createRoot } from 'react-dom/client';
import '@sd/ui/style';
// bind state to core via Tauri
class Transport extends BaseTransport {

View file

@ -1,7 +1,8 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
import svg from 'vite-plugin-svgr';
import { name, version } from './package.json';
import svg from "vite-plugin-svgr"
// https://vitejs.dev/config/
export default defineConfig({

View file

@ -28,12 +28,12 @@
* --syntax-cursor-line: hsla(220, 100%, 80%, 0.04);
*/
code[class*="language-"],
pre[class*="language-"] {
code[class*='language-'],
pre[class*='language-'] {
background: hsl(220, 9%, 6%);
color: hsl(220, 14%, 71%);
text-shadow: 0 1px rgba(0, 0, 0, 0.3);
font-family: "Fira Code", "Fira Mono", Menlo, Consolas, "DejaVu Sans Mono", monospace;
font-family: 'Fira Code', 'Fira Mono', Menlo, Consolas, 'DejaVu Sans Mono', monospace;
direction: ltr;
text-align: left;
white-space: pre;
@ -47,394 +47,397 @@
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
}
/* Selection */
code[class*="language-"]::-moz-selection,
code[class*="language-"] *::-moz-selection,
pre[class*="language-"] *::-moz-selection {
/* Selection */
code[class*='language-']::-moz-selection,
code[class*='language-'] *::-moz-selection,
pre[class*='language-'] *::-moz-selection {
background: hsl(220, 13%, 28%);
color: inherit;
text-shadow: none;
}
}
code[class*="language-"]::selection,
code[class*="language-"] *::selection,
pre[class*="language-"] *::selection {
code[class*='language-']::selection,
code[class*='language-'] *::selection,
pre[class*='language-'] *::selection {
background: hsl(220, 13%, 28%);
color: inherit;
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
/* Code blocks */
pre[class*='language-'] {
padding: 1em;
margin: 0.5em 0;
overflow: auto;
border-radius: 0.3em;
}
}
/* Inline code */
:not(pre) > code[class*="language-"] {
/* Inline code */
:not(pre) > code[class*='language-'] {
padding: 0.2em 0.3em;
border-radius: 0.3em;
white-space: normal;
}
}
/* Print */
@media print {
code[class*="language-"],
pre[class*="language-"] {
/* Print */
@media print {
code[class*='language-'],
pre[class*='language-'] {
text-shadow: none;
}
}
}
.token.comment,
.token.prolog,
.token.cdata {
.token.comment,
.token.prolog,
.token.cdata {
color: hsl(220, 10%, 40%);
}
}
.token.doctype,
.token.punctuation,
.token.entity {
.token.doctype,
.token.punctuation,
.token.entity {
color: hsl(220, 14%, 71%);
}
}
.token.attr-name,
.token.class-name,
.token.boolean,
.token.constant,
.token.number,
.token.atrule {
.token.attr-name,
.token.class-name,
.token.boolean,
.token.constant,
.token.number,
.token.atrule {
color: hsl(29, 54%, 61%);
}
}
.token.keyword {
.token.keyword {
color: hsl(286, 60%, 67%);
}
}
.token.property,
.token.tag,
.token.symbol,
.token.deleted,
.token.important {
.token.property,
.token.tag,
.token.symbol,
.token.deleted,
.token.important {
color: hsl(355, 65%, 65%);
}
}
.token.selector,
.token.string,
.token.char,
.token.builtin,
.token.inserted,
.token.regex,
.token.attr-value,
.token.attr-value > .token.punctuation {
.token.selector,
.token.string,
.token.char,
.token.builtin,
.token.inserted,
.token.regex,
.token.attr-value,
.token.attr-value > .token.punctuation {
color: hsl(95, 38%, 62%);
}
}
.token.variable,
.token.operator,
.token.function {
.token.variable,
.token.operator,
.token.function {
color: hsl(207, 82%, 66%);
}
}
.token.url {
.token.url {
color: hsl(187, 47%, 55%);
}
}
/* HTML overrides */
.token.attr-value > .token.punctuation.attr-equals,
.token.special-attr > .token.attr-value > .token.value.css {
/* HTML overrides */
.token.attr-value > .token.punctuation.attr-equals,
.token.special-attr > .token.attr-value > .token.value.css {
color: hsl(220, 14%, 71%);
}
}
/* CSS overrides */
.language-css .token.selector {
/* CSS overrides */
.language-css .token.selector {
color: hsl(355, 65%, 65%);
}
}
.language-css .token.property {
.language-css .token.property {
color: hsl(220, 14%, 71%);
}
}
.language-css .token.function,
.language-css .token.url > .token.function {
.language-css .token.function,
.language-css .token.url > .token.function {
color: hsl(187, 47%, 55%);
}
}
.language-css .token.url > .token.string.url {
.language-css .token.url > .token.string.url {
color: hsl(95, 38%, 62%);
}
}
.language-css .token.important,
.language-css .token.atrule .token.rule {
.language-css .token.important,
.language-css .token.atrule .token.rule {
color: hsl(286, 60%, 67%);
}
}
/* JS overrides */
.language-javascript .token.operator {
/* JS overrides */
.language-javascript .token.operator {
color: hsl(286, 60%, 67%);
}
}
.language-javascript .token.template-string > .token.interpolation > .token.interpolation-punctuation.punctuation {
.language-javascript
.token.template-string
> .token.interpolation
> .token.interpolation-punctuation.punctuation {
color: hsl(5, 48%, 51%);
}
}
/* JSON overrides */
.language-json .token.operator {
/* JSON overrides */
.language-json .token.operator {
color: hsl(220, 14%, 71%);
}
}
.language-json .token.null.keyword {
.language-json .token.null.keyword {
color: hsl(29, 54%, 61%);
}
}
/* MD overrides */
.language-markdown .token.url,
.language-markdown .token.url > .token.operator,
.language-markdown .token.url-reference.url > .token.string {
/* MD overrides */
.language-markdown .token.url,
.language-markdown .token.url > .token.operator,
.language-markdown .token.url-reference.url > .token.string {
color: hsl(220, 14%, 71%);
}
}
.language-markdown .token.url > .token.content {
.language-markdown .token.url > .token.content {
color: hsl(207, 82%, 66%);
}
}
.language-markdown .token.url > .token.url,
.language-markdown .token.url-reference.url {
.language-markdown .token.url > .token.url,
.language-markdown .token.url-reference.url {
color: hsl(187, 47%, 55%);
}
}
.language-markdown .token.blockquote.punctuation,
.language-markdown .token.hr.punctuation {
.language-markdown .token.blockquote.punctuation,
.language-markdown .token.hr.punctuation {
color: hsl(220, 10%, 40%);
font-style: italic;
}
}
.language-markdown .token.code-snippet {
.language-markdown .token.code-snippet {
color: hsl(95, 38%, 62%);
}
}
.language-markdown .token.bold .token.content {
.language-markdown .token.bold .token.content {
color: hsl(29, 54%, 61%);
}
}
.language-markdown .token.italic .token.content {
.language-markdown .token.italic .token.content {
color: hsl(286, 60%, 67%);
}
}
.language-markdown .token.strike .token.content,
.language-markdown .token.strike .token.punctuation,
.language-markdown .token.list.punctuation,
.language-markdown .token.title.important > .token.punctuation {
.language-markdown .token.strike .token.content,
.language-markdown .token.strike .token.punctuation,
.language-markdown .token.list.punctuation,
.language-markdown .token.title.important > .token.punctuation {
color: hsl(355, 65%, 65%);
}
}
/* General */
.token.bold {
/* General */
.token.bold {
font-weight: bold;
}
}
.token.comment,
.token.italic {
.token.comment,
.token.italic {
font-style: italic;
}
}
.token.entity {
.token.entity {
cursor: help;
}
}
.token.namespace {
.token.namespace {
opacity: 0.8;
}
}
/* Plugin overrides */
/* Selectors should have higher specificity than those in the plugins' default stylesheets */
/* Plugin overrides */
/* Selectors should have higher specificity than those in the plugins' default stylesheets */
/* Show Invisibles plugin overrides */
.token.token.tab:not(:empty):before,
.token.token.cr:before,
.token.token.lf:before,
.token.token.space:before {
/* Show Invisibles plugin overrides */
.token.token.tab:not(:empty):before,
.token.token.cr:before,
.token.token.lf:before,
.token.token.space:before {
color: hsla(220, 14%, 71%, 0.15);
text-shadow: none;
}
}
/* Toolbar plugin overrides */
/* Space out all buttons and move them away from the right edge of the code block */
div.code-toolbar > .toolbar.toolbar > .toolbar-item {
/* Toolbar plugin overrides */
/* Space out all buttons and move them away from the right edge of the code block */
div.code-toolbar > .toolbar.toolbar > .toolbar-item {
margin-right: 0.4em;
}
}
/* Styling the buttons */
div.code-toolbar > .toolbar.toolbar > .toolbar-item > button,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > a,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span {
/* Styling the buttons */
div.code-toolbar > .toolbar.toolbar > .toolbar-item > button,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > a,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span {
background: hsl(220, 13%, 26%);
color: hsl(220, 9%, 55%);
padding: 0.1em 0.4em;
border-radius: 0.3em;
}
}
div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:focus,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:hover,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus {
div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:focus,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:hover,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus {
background: hsl(220, 13%, 28%);
color: hsl(220, 14%, 71%);
}
}
/* Line Highlight plugin overrides */
/* The highlighted line itself */
.line-highlight.line-highlight {
/* Line Highlight plugin overrides */
/* The highlighted line itself */
.line-highlight.line-highlight {
background: hsla(220, 100%, 80%, 0.04);
}
}
/* Default line numbers in Line Highlight plugin */
.line-highlight.line-highlight:before,
.line-highlight.line-highlight[data-end]:after {
/* Default line numbers in Line Highlight plugin */
.line-highlight.line-highlight:before,
.line-highlight.line-highlight[data-end]:after {
background: hsl(220, 13%, 26%);
color: hsl(220, 14%, 71%);
padding: 0.1em 0.6em;
border-radius: 0.3em;
box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.2); /* same as Toolbar plugin default */
}
}
/* Hovering over a linkable line number (in the gutter area) */
/* Requires Line Numbers plugin as well */
pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > span:hover:before {
/* Hovering over a linkable line number (in the gutter area) */
/* Requires Line Numbers plugin as well */
pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > span:hover:before {
background-color: hsla(220, 100%, 80%, 0.04);
}
}
/* Line Numbers and Command Line plugins overrides */
/* Line separating gutter from coding area */
.line-numbers.line-numbers .line-numbers-rows,
.command-line .command-line-prompt {
/* Line Numbers and Command Line plugins overrides */
/* Line separating gutter from coding area */
.line-numbers.line-numbers .line-numbers-rows,
.command-line .command-line-prompt {
border-right-color: hsla(220, 14%, 71%, 0.15);
}
}
/* Stuff in the gutter */
.line-numbers .line-numbers-rows > span:before,
.command-line .command-line-prompt > span:before {
/* Stuff in the gutter */
.line-numbers .line-numbers-rows > span:before,
.command-line .command-line-prompt > span:before {
color: hsl(220, 14%, 45%);
}
}
/* Match Braces plugin overrides */
/* Note: Outline colour is inherited from the braces */
.rainbow-braces .token.token.punctuation.brace-level-1,
.rainbow-braces .token.token.punctuation.brace-level-5,
.rainbow-braces .token.token.punctuation.brace-level-9 {
/* Match Braces plugin overrides */
/* Note: Outline colour is inherited from the braces */
.rainbow-braces .token.token.punctuation.brace-level-1,
.rainbow-braces .token.token.punctuation.brace-level-5,
.rainbow-braces .token.token.punctuation.brace-level-9 {
color: hsl(355, 65%, 65%);
}
}
.rainbow-braces .token.token.punctuation.brace-level-2,
.rainbow-braces .token.token.punctuation.brace-level-6,
.rainbow-braces .token.token.punctuation.brace-level-10 {
.rainbow-braces .token.token.punctuation.brace-level-2,
.rainbow-braces .token.token.punctuation.brace-level-6,
.rainbow-braces .token.token.punctuation.brace-level-10 {
color: hsl(95, 38%, 62%);
}
}
.rainbow-braces .token.token.punctuation.brace-level-3,
.rainbow-braces .token.token.punctuation.brace-level-7,
.rainbow-braces .token.token.punctuation.brace-level-11 {
.rainbow-braces .token.token.punctuation.brace-level-3,
.rainbow-braces .token.token.punctuation.brace-level-7,
.rainbow-braces .token.token.punctuation.brace-level-11 {
color: hsl(207, 82%, 66%);
}
}
.rainbow-braces .token.token.punctuation.brace-level-4,
.rainbow-braces .token.token.punctuation.brace-level-8,
.rainbow-braces .token.token.punctuation.brace-level-12 {
.rainbow-braces .token.token.punctuation.brace-level-4,
.rainbow-braces .token.token.punctuation.brace-level-8,
.rainbow-braces .token.token.punctuation.brace-level-12 {
color: hsl(286, 60%, 67%);
}
}
/* Diff Highlight plugin overrides */
/* Taken from https://github.com/atom/github/blob/master/styles/variables.less */
pre.diff-highlight > code .token.token.deleted:not(.prefix),
pre > code.diff-highlight .token.token.deleted:not(.prefix) {
/* Diff Highlight plugin overrides */
/* Taken from https://github.com/atom/github/blob/master/styles/variables.less */
pre.diff-highlight > code .token.token.deleted:not(.prefix),
pre > code.diff-highlight .token.token.deleted:not(.prefix) {
background-color: hsla(353, 100%, 66%, 0.15);
}
}
pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection,
pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection {
pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection,
pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection {
background-color: hsla(353, 95%, 66%, 0.25);
}
}
pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection,
pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection {
pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection,
pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection {
background-color: hsla(353, 95%, 66%, 0.25);
}
}
pre.diff-highlight > code .token.token.inserted:not(.prefix),
pre > code.diff-highlight .token.token.inserted:not(.prefix) {
pre.diff-highlight > code .token.token.inserted:not(.prefix),
pre > code.diff-highlight .token.token.inserted:not(.prefix) {
background-color: hsla(137, 100%, 55%, 0.15);
}
}
pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection,
pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection {
pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection,
pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection {
background-color: hsla(135, 73%, 55%, 0.25);
}
}
pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection,
pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection {
pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection,
pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection {
background-color: hsla(135, 73%, 55%, 0.25);
}
}
/* Previewers plugin overrides */
/* Based on https://github.com/atom-community/atom-ide-datatip/blob/master/styles/atom-ide-datatips.less and https://github.com/atom/atom/blob/master/packages/one-dark-ui */
/* Border around popup */
.prism-previewer.prism-previewer:before,
.prism-previewer-gradient.prism-previewer-gradient div {
/* Previewers plugin overrides */
/* Based on https://github.com/atom-community/atom-ide-datatip/blob/master/styles/atom-ide-datatips.less and https://github.com/atom/atom/blob/master/packages/one-dark-ui */
/* Border around popup */
.prism-previewer.prism-previewer:before,
.prism-previewer-gradient.prism-previewer-gradient div {
border-color: hsl(224, 13%, 17%);
}
}
/* Angle and time should remain as circles and are hence not included */
.prism-previewer-color.prism-previewer-color:before,
.prism-previewer-gradient.prism-previewer-gradient div,
.prism-previewer-easing.prism-previewer-easing:before {
/* Angle and time should remain as circles and are hence not included */
.prism-previewer-color.prism-previewer-color:before,
.prism-previewer-gradient.prism-previewer-gradient div,
.prism-previewer-easing.prism-previewer-easing:before {
border-radius: 0.3em;
}
}
/* Triangles pointing to the code */
.prism-previewer.prism-previewer:after {
/* Triangles pointing to the code */
.prism-previewer.prism-previewer:after {
border-top-color: hsl(224, 13%, 17%);
}
}
.prism-previewer-flipped.prism-previewer-flipped.after {
.prism-previewer-flipped.prism-previewer-flipped.after {
border-bottom-color: hsl(224, 13%, 17%);
}
}
/* Background colour within the popup */
.prism-previewer-angle.prism-previewer-angle:before,
.prism-previewer-time.prism-previewer-time:before,
.prism-previewer-easing.prism-previewer-easing {
/* Background colour within the popup */
.prism-previewer-angle.prism-previewer-angle:before,
.prism-previewer-time.prism-previewer-time:before,
.prism-previewer-easing.prism-previewer-easing {
background: hsl(219, 13%, 22%);
}
}
/* For angle, this is the positive area (eg. 90deg will display one quadrant in this colour) */
/* For time, this is the alternate colour */
.prism-previewer-angle.prism-previewer-angle circle,
.prism-previewer-time.prism-previewer-time circle {
/* For angle, this is the positive area (eg. 90deg will display one quadrant in this colour) */
/* For time, this is the alternate colour */
.prism-previewer-angle.prism-previewer-angle circle,
.prism-previewer-time.prism-previewer-time circle {
stroke: hsl(220, 14%, 71%);
stroke-opacity: 1;
}
}
/* Stroke colours of the handle, direction point, and vector itself */
.prism-previewer-easing.prism-previewer-easing circle,
.prism-previewer-easing.prism-previewer-easing path,
.prism-previewer-easing.prism-previewer-easing line {
/* Stroke colours of the handle, direction point, and vector itself */
.prism-previewer-easing.prism-previewer-easing circle,
.prism-previewer-easing.prism-previewer-easing path,
.prism-previewer-easing.prism-previewer-easing line {
stroke: hsl(220, 14%, 71%);
}
}
/* Fill colour of the handle */
.prism-previewer-easing.prism-previewer-easing circle {
/* Fill colour of the handle */
.prism-previewer-easing.prism-previewer-easing circle {
fill: transparent;
}
}

View file

@ -1,13 +1,14 @@
import React from 'react';
import { ReactComponent as AppLogo } from '../assets/app-logo.svg';
import {
Twitter,
Discord,
Instagram,
Github,
Instagram,
Opencollective,
Twitch
Twitch,
Twitter
} from '@icons-pack/react-simple-icons';
import React from 'react';
import { ReactComponent as AppLogo } from '../assets/app-logo.svg';
function FooterLink(props: { children: string | JSX.Element; link: string }) {
return (

View file

@ -1,7 +1,7 @@
import React, { useEffect } from 'react';
import Prism from 'prismjs';
import 'prismjs/components/prism-rust';
import React, { useEffect } from 'react';
import '../atom-one.css';
interface MarkdownPageProps {

View file

@ -1,9 +1,3 @@
import { Button, Dropdown } from '@sd/ui';
import clsx from 'clsx';
import React, { useEffect, useState } from 'react';
import { Link, List, MapPin, Question } from 'phosphor-react';
import { ReactComponent as AppLogo } from '../assets/app-logo.svg';
import { Discord, Github } from '@icons-pack/react-simple-icons';
import {
ClockIcon,
CogIcon,
@ -12,6 +6,13 @@ import {
MapIcon,
QuestionMarkCircleIcon
} from '@heroicons/react/solid';
import { Discord, Github } from '@icons-pack/react-simple-icons';
import { Button, Dropdown } from '@sd/ui';
import clsx from 'clsx';
import { Link, List, MapPin, Question } from 'phosphor-react';
import React, { useEffect, useState } from 'react';
import { ReactComponent as AppLogo } from '../assets/app-logo.svg';
function NavLink(props: { link?: string; children: string }) {
return (

View file

@ -1,14 +1,14 @@
import { Button } from '@sd/ui';
import React, { Suspense } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter as Router, useRoutes } from 'react-router-dom';
import routes from '~react-pages';
import NavBar from './components/NavBar';
import { Footer } from './components/Footer';
import '@sd/ui/style';
import { Footer } from './components/Footer';
import NavBar from './components/NavBar';
import './style.scss';
import { Button } from '@sd/ui';
function App() {
return (

View file

@ -1,8 +1,9 @@
import Markdown from '../components/Markdown';
import React from 'react';
import { Helmet } from 'react-helmet';
import { Button } from '@sd/ui';
import { SmileyXEyes } from 'phosphor-react';
import React from 'react';
import { Helmet } from 'react-helmet';
import Markdown from '../components/Markdown';
function Page() {
return (

View file

@ -1,7 +1,8 @@
import Markdown from '../components/Markdown';
import React from 'react';
import { ReactComponent as Content } from '~/docs/changelog/index.md';
import { Helmet } from 'react-helmet';
import { ReactComponent as Content } from '~/docs/changelog/index.md';
import Markdown from '../components/Markdown';
function Page() {
return (

View file

@ -1,7 +1,8 @@
import Markdown from '../../../components/Markdown';
import React from 'react';
import { ReactComponent as Content } from '~/docs/architecture/distributed-data-sync.md';
import { Helmet } from 'react-helmet';
import { ReactComponent as Content } from '~/docs/architecture/distributed-data-sync.md';
import Markdown from '../../../components/Markdown';
function Page() {
return (

View file

@ -1,7 +1,8 @@
import Markdown from '../components/Markdown';
import React from 'react';
import { ReactComponent as Content } from '~/docs/product/faq.md';
import { Helmet } from 'react-helmet';
import { ReactComponent as Content } from '~/docs/product/faq.md';
import Markdown from '../components/Markdown';
function Page() {
return (

View file

@ -1,13 +1,13 @@
import React, { useEffect } from 'react';
import { Button } from '@sd/ui';
import { Bubbles } from '../components/Bubbles';
import NavBar from '../components/NavBar';
import { Footer } from '../components/Footer';
import { Apple, Github, Linux, Windows } from '@icons-pack/react-simple-icons';
import { useState } from 'react';
import { Button } from '@sd/ui';
import clsx from 'clsx';
import React, { useEffect } from 'react';
import { useState } from 'react';
import AppEmbed from '../components/AppEmbed';
import { Bubbles } from '../components/Bubbles';
import { Footer } from '../components/Footer';
import NavBar from '../components/NavBar';
interface SectionProps {
orientation: 'left' | 'right';

View file

@ -1,8 +1,9 @@
import Markdown from '../components/Markdown';
import React from 'react';
import { ReactComponent as Content } from '~/docs/product/roadmap.md';
import { Helmet } from 'react-helmet';
import { ReactComponent as Content } from '~/docs/product/roadmap.md';
import { ReactComponent as Folder } from '../../../../packages/interface/src/assets/svg/folder.svg';
import Markdown from '../components/Markdown';
function Page() {
return (

View file

@ -1,7 +1,8 @@
import Markdown from '../components/Markdown';
import React from 'react';
import { ReactComponent as Content } from '~/docs/product/credits.md';
import { Helmet } from 'react-helmet';
import { ReactComponent as Content } from '~/docs/product/credits.md';
import Markdown from '../components/Markdown';
function Page() {
return (

View file

@ -1,7 +1,7 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import pages from 'vite-plugin-pages';
import { defineConfig } from 'vite';
import md, { Mode } from 'vite-plugin-markdown';
import pages from 'vite-plugin-pages';
import svg from 'vite-plugin-svgr';
// https://vitejs.dev/config/

View file

@ -1,8 +1,7 @@
import React, { useEffect } from 'react';
import SpacedriveInterface from '@sd/interface';
import { ClientCommand, ClientQuery, CoreEvent } from '@sd/core';
import { BaseTransport } from '@sd/client';
import { ClientCommand, ClientQuery, CoreEvent } from '@sd/core';
import SpacedriveInterface from '@sd/interface';
import React, { useEffect } from 'react';
const websocket = new WebSocket(import.meta.env.VITE_SDSERVER_BASE_URL || 'ws://localhost:8080/ws');

View file

@ -1,8 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import '@sd/ui/style';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
root.render(
<React.StrictMode>

View file

@ -1,5 +1,5 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
import svg from 'vite-plugin-svgr';
import tsconfigPaths from 'vite-plugin-tsconfig-paths';

View file

@ -1,6 +1,5 @@
max_width = 100
hard_tabs = false
tab_spaces = 2
hard_tabs = true
newline_style = "Unix"
use_small_heuristics = "Default"
reorder_imports = true

View file

@ -1,3 +1,10 @@
import type { Platform } from "./Platform";
import type { Platform } from './Platform';
export interface Client { uuid: string, name: string, platform: Platform, tcp_address: string, last_seen: string, last_synchronized: string, }
export interface Client {
uuid: string;
name: string;
platform: Platform;
tcp_address: string;
last_seen: string;
last_synchronized: string;
}

View file

@ -1,2 +1,14 @@
export type ClientCommand = { key: "FileRead", params: { id: number, } } | { key: "FileDelete", params: { id: number, } } | { key: "LibDelete", params: { id: number, } } | { key: "TagCreate", params: { name: string, color: string, } } | { key: "TagUpdate", params: { name: string, color: string, } } | { key: "TagAssign", params: { file_id: number, tag_id: number, } } | { key: "TagDelete", params: { id: number, } } | { key: "LocCreate", params: { path: string, } } | { key: "LocUpdate", params: { id: number, name: string | null, } } | { key: "LocDelete", params: { id: number, } } | { key: "SysVolumeUnmount", params: { id: number, } } | { key: "GenerateThumbsForLocation", params: { id: number, path: string, } } | { key: "IdentifyUniqueFiles" };
export type ClientCommand =
| { key: 'FileRead'; params: { id: number } }
| { key: 'FileDelete'; params: { id: number } }
| { key: 'LibDelete'; params: { id: number } }
| { key: 'TagCreate'; params: { name: string; color: string } }
| { key: 'TagUpdate'; params: { name: string; color: string } }
| { key: 'TagAssign'; params: { file_id: number; tag_id: number } }
| { key: 'TagDelete'; params: { id: number } }
| { key: 'LocCreate'; params: { path: string } }
| { key: 'LocUpdate'; params: { id: number; name: string | null } }
| { key: 'LocDelete'; params: { id: number } }
| { key: 'SysVolumeUnmount'; params: { id: number } }
| { key: 'GenerateThumbsForLocation'; params: { id: number; path: string } }
| { key: 'IdentifyUniqueFiles' };

View file

@ -1,2 +1,10 @@
export type ClientQuery = { key: "ClientGetState" } | { key: "SysGetVolumes" } | { key: "LibGetTags" } | { key: "JobGetRunning" } | { key: "JobGetHistory" } | { key: "SysGetLocations" } | { key: "SysGetLocation", params: { id: number, } } | { key: "LibGetExplorerDir", params: { location_id: number, path: string, limit: number, } } | { key: "GetLibraryStatistics" };
export type ClientQuery =
| { key: 'ClientGetState' }
| { key: 'SysGetVolumes' }
| { key: 'LibGetTags' }
| { key: 'JobGetRunning' }
| { key: 'JobGetHistory' }
| { key: 'SysGetLocations' }
| { key: 'SysGetLocation'; params: { id: number } }
| { key: 'LibGetExplorerDir'; params: { location_id: number; path: string; limit: number } }
| { key: 'GetLibraryStatistics' };

View file

@ -1,3 +1,11 @@
import type { LibraryState } from "./LibraryState";
import type { LibraryState } from './LibraryState';
export interface ClientState { client_uuid: string, client_id: number, client_name: string, data_path: string, tcp_port: number, libraries: Array<LibraryState>, current_library_uuid: string, }
export interface ClientState {
client_uuid: string;
client_id: number;
client_name: string;
data_path: string;
tcp_port: number;
libraries: Array<LibraryState>;
current_library_uuid: string;
}

View file

@ -1,4 +1,10 @@
import type { ClientQuery } from "./ClientQuery";
import type { CoreResource } from "./CoreResource";
import type { ClientQuery } from './ClientQuery';
import type { CoreResource } from './CoreResource';
export type CoreEvent = { key: "InvalidateQuery", data: ClientQuery } | { key: "InvalidateQueryDebounced", data: ClientQuery } | { key: "InvalidateResource", data: CoreResource } | { key: "NewThumbnail", data: { cas_id: string, } } | { key: "Log", data: { message: string, } } | { key: "DatabaseDisconnected", data: { reason: string | null, } };
export type CoreEvent =
| { key: 'InvalidateQuery'; data: ClientQuery }
| { key: 'InvalidateQueryDebounced'; data: ClientQuery }
| { key: 'InvalidateResource'; data: CoreResource }
| { key: 'NewThumbnail'; data: { cas_id: string } }
| { key: 'Log'; data: { message: string } }
| { key: 'DatabaseDisconnected'; data: { reason: string | null } };

View file

@ -1,5 +1,11 @@
import type { File } from "./File";
import type { JobReport } from "./JobReport";
import type { LocationResource } from "./LocationResource";
import type { File } from './File';
import type { JobReport } from './JobReport';
import type { LocationResource } from './LocationResource';
export type CoreResource = "Client" | "Library" | { Location: LocationResource } | { File: File } | { Job: JobReport } | "Tag";
export type CoreResource =
| 'Client'
| 'Library'
| { Location: LocationResource }
| { File: File }
| { Job: JobReport }
| 'Tag';

View file

@ -1,8 +1,18 @@
import type { ClientState } from "./ClientState";
import type { DirectoryWithContents } from "./DirectoryWithContents";
import type { JobReport } from "./JobReport";
import type { LocationResource } from "./LocationResource";
import type { Statistics } from "./Statistics";
import type { Volume } from "./Volume";
import type { ClientState } from './ClientState';
import type { DirectoryWithContents } from './DirectoryWithContents';
import type { JobReport } from './JobReport';
import type { LocationResource } from './LocationResource';
import type { Statistics } from './Statistics';
import type { Volume } from './Volume';
export type CoreResponse = { key: "Success", data: null } | { key: "SysGetVolumes", data: Array<Volume> } | { key: "SysGetLocation", data: LocationResource } | { key: "SysGetLocations", data: Array<LocationResource> } | { key: "LibGetExplorerDir", data: DirectoryWithContents } | { key: "ClientGetState", data: ClientState } | { key: "LocCreate", data: LocationResource } | { key: "JobGetRunning", data: Array<JobReport> } | { key: "JobGetHistory", data: Array<JobReport> } | { key: "GetLibraryStatistics", data: Statistics };
export type CoreResponse =
| { key: 'Success'; data: null }
| { key: 'SysGetVolumes'; data: Array<Volume> }
| { key: 'SysGetLocation'; data: LocationResource }
| { key: 'SysGetLocations'; data: Array<LocationResource> }
| { key: 'LibGetExplorerDir'; data: DirectoryWithContents }
| { key: 'ClientGetState'; data: ClientState }
| { key: 'LocCreate'; data: LocationResource }
| { key: 'JobGetRunning'; data: Array<JobReport> }
| { key: 'JobGetHistory'; data: Array<JobReport> }
| { key: 'GetLibraryStatistics'; data: Statistics };

View file

@ -1,3 +1,6 @@
import type { FilePath } from "./FilePath";
import type { FilePath } from './FilePath';
export interface DirectoryWithContents { directory: FilePath, contents: Array<FilePath>, }
export interface DirectoryWithContents {
directory: FilePath;
contents: Array<FilePath>;
}

View file

@ -1,2 +1 @@
export type EncryptionAlgorithm = "None" | "AES128" | "AES192" | "AES256";
export type EncryptionAlgorithm = 'None' | 'AES128' | 'AES192' | 'AES256';

View file

@ -1,5 +1,24 @@
import type { EncryptionAlgorithm } from "./EncryptionAlgorithm";
import type { FileKind } from "./FileKind";
import type { FilePath } from "./FilePath";
import type { EncryptionAlgorithm } from './EncryptionAlgorithm';
import type { FileKind } from './FileKind';
import type { FilePath } from './FilePath';
export interface File { id: number, cas_id: string, integrity_checksum: string | null, size_in_bytes: string, kind: FileKind, hidden: boolean, favorite: boolean, important: boolean, has_thumbnail: boolean, has_thumbstrip: boolean, has_video_preview: boolean, encryption: EncryptionAlgorithm, ipfs_id: string | null, comment: string | null, date_created: string, date_modified: string, date_indexed: string, paths: Array<FilePath>, }
export interface File {
id: number;
cas_id: string;
integrity_checksum: string | null;
size_in_bytes: string;
kind: FileKind;
hidden: boolean;
favorite: boolean;
important: boolean;
has_thumbnail: boolean;
has_thumbstrip: boolean;
has_video_preview: boolean;
encryption: EncryptionAlgorithm;
ipfs_id: string | null;
comment: string | null;
date_created: string;
date_modified: string;
date_indexed: string;
paths: Array<FilePath>;
}

View file

@ -1,2 +1,10 @@
export type FileKind = "Unknown" | "Directory" | "Package" | "Archive" | "Image" | "Video" | "Audio" | "Plaintext" | "Alias";
export type FileKind =
| 'Unknown'
| 'Directory'
| 'Package'
| 'Archive'
| 'Image'
| 'Video'
| 'Audio'
| 'Plaintext'
| 'Alias';

View file

@ -1,2 +1,16 @@
export interface FilePath { id: number, is_dir: boolean, location_id: number, materialized_path: string, name: string, extension: string | null, file_id: number | null, parent_id: number | null, temp_cas_id: string | null, has_local_thumbnail: boolean, date_created: string, date_modified: string, date_indexed: string, permissions: string | null, }
export interface FilePath {
id: number;
is_dir: boolean;
location_id: number;
materialized_path: string;
name: string;
extension: string | null;
file_id: number | null;
parent_id: number | null;
temp_cas_id: string | null;
has_local_thumbnail: boolean;
date_created: string;
date_modified: string;
date_indexed: string;
permissions: string | null;
}

View file

@ -1,3 +1,12 @@
import type { JobStatus } from "./JobStatus";
import type { JobStatus } from './JobStatus';
export interface JobReport { id: string, date_created: string, date_modified: string, status: JobStatus, task_count: number, completed_task_count: number, message: string, seconds_elapsed: string, }
export interface JobReport {
id: string;
date_created: string;
date_modified: string;
status: JobStatus;
task_count: number;
completed_task_count: number;
message: string;
seconds_elapsed: string;
}

View file

@ -1,2 +1 @@
export type JobStatus = "Queued" | "Running" | "Completed" | "Canceled" | "Failed";
export type JobStatus = 'Queued' | 'Running' | 'Completed' | 'Canceled' | 'Failed';

View file

@ -1,2 +1,6 @@
export interface LibraryState { library_uuid: string, library_id: number, library_path: string, offline: boolean, }
export interface LibraryState {
library_uuid: string;
library_id: number;
library_path: string;
offline: boolean;
}

View file

@ -1,2 +1,10 @@
export interface LocationResource { id: number, name: string | null, path: string | null, total_capacity: number | null, available_capacity: number | null, is_removable: boolean | null, is_online: boolean, date_created: string, }
export interface LocationResource {
id: number;
name: string | null;
path: string | null;
total_capacity: number | null;
available_capacity: number | null;
is_removable: boolean | null;
is_online: boolean;
date_created: string;
}

View file

@ -1,2 +1 @@
export type Platform = "Unknown" | "Windows" | "MacOS" | "Linux" | "IOS" | "Android";
export type Platform = 'Unknown' | 'Windows' | 'MacOS' | 'Linux' | 'IOS' | 'Android';

View file

@ -1,2 +1,9 @@
export interface Statistics { total_file_count: number, total_bytes_used: string, total_bytes_capacity: string, total_bytes_free: string, total_unique_bytes: string, preview_media_bytes: string, library_db_size: string, }
export interface Statistics {
total_file_count: number;
total_bytes_used: string;
total_bytes_capacity: string;
total_bytes_free: string;
total_unique_bytes: string;
preview_media_bytes: string;
library_db_size: string;
}

View file

@ -1,2 +1,10 @@
export interface Volume { name: string, mount_point: string, total_capacity: bigint, available_capacity: bigint, is_removable: boolean, disk_type: string | null, file_system: string | null, is_root_filesystem: boolean, }
export interface Volume {
name: string;
mount_point: string;
total_capacity: bigint;
available_capacity: bigint;
is_removable: boolean;
disk_type: string | null;
file_system: string | null;
is_root_filesystem: boolean;
}

View file

@ -45,7 +45,9 @@ pub async fn run_migrations(ctx: &CoreContext) -> Result<()> {
};
let value: Vec<serde_json::Value> = client
._query_raw("SELECT name FROM sqlite_master WHERE type='table' AND name='_migrations'")
._query_raw(
"SELECT name FROM sqlite_master WHERE type='table' AND name='_migrations'",
)
.await
.unwrap();

View file

@ -51,7 +51,10 @@ impl Job for ThumbnailJob {
tokio::task::spawn_blocking(move || {
ctx.progress(vec![
JobReportUpdate::TaskCount(image_files.len()),
JobReportUpdate::Message(format!("Preparing to process {} files", image_files.len())),
JobReportUpdate::Message(format!(
"Preparing to process {} files",
image_files.len()
)),
]);
for (i, image_file) in image_files.iter().enumerate() {

View file

@ -0,0 +1 @@

View file

@ -0,0 +1 @@

View file

@ -2,13 +2,13 @@ use crate::job::jobs::JobReportUpdate;
use crate::{
file::FileError,
job::{jobs::Job, worker::WorkerContext},
prisma::{file_path},
prisma::file_path,
CoreContext,
};
use anyhow::Result;
use futures::executor::block_on;
use serde::{Deserialize, Serialize};
use prisma_client_rust::Direction;
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize, Debug)]
pub struct FileCreated {
@ -88,7 +88,10 @@ impl Job for FileIdentifierJob {
let remaining = count_orphan_file_paths(&ctx.core_ctx).await?;
println!("Finished with {} files remaining because your code is bad.", remaining);
println!(
"Finished with {} files remaining because your code is bad.",
remaining
);
// if remaining > 0 {
// ctx.core_ctx.spawn_job(Box::new(FileIdentifierJob));

View file

@ -135,8 +135,7 @@ impl JobReport {
}
pub async fn create(&self, ctx: &CoreContext) -> Result<(), JobError> {
let config = state::client::get();
ctx
.database
ctx.database
.job()
.create(
job::id::set(self.id.clone()),
@ -149,8 +148,7 @@ impl JobReport {
Ok(())
}
pub async fn update(&self, ctx: &CoreContext) -> Result<(), JobError> {
ctx
.database
ctx.database
.job()
.find_unique(job::id::equals(self.id.clone()))
.update(vec![

View file

@ -29,8 +29,7 @@ pub struct WorkerContext {
impl WorkerContext {
pub fn progress(&self, updates: Vec<JobReportUpdate>) {
self
.sender
self.sender
.send(WorkerEvent::Progressed(updates))
.unwrap_or(());
}
@ -147,7 +146,8 @@ impl Worker {
worker.job_report.task_count = task_count as i32;
}
JobReportUpdate::CompletedTaskCount(completed_task_count) => {
worker.job_report.completed_task_count = completed_task_count as i32;
worker.job_report.completed_task_count =
completed_task_count as i32;
}
JobReportUpdate::Message(message) => {
worker.job_report.message = message;
@ -157,8 +157,7 @@ impl Worker {
}
}
}
ctx
.emit(CoreEvent::InvalidateQueryDebounced(
ctx.emit(CoreEvent::InvalidateQueryDebounced(
ClientQuery::JobGetRunning,
))
.await;
@ -167,11 +166,9 @@ impl Worker {
worker.job_report.status = JobStatus::Completed;
worker.job_report.update(&ctx).await.unwrap_or(());
ctx
.emit(CoreEvent::InvalidateQuery(ClientQuery::JobGetRunning))
ctx.emit(CoreEvent::InvalidateQuery(ClientQuery::JobGetRunning))
.await;
ctx
.emit(CoreEvent::InvalidateQuery(ClientQuery::JobGetHistory))
ctx.emit(CoreEvent::InvalidateQuery(ClientQuery::JobGetHistory))
.await;
break;
}
@ -179,8 +176,7 @@ impl Worker {
worker.job_report.status = JobStatus::Failed;
worker.job_report.update(&ctx).await.unwrap_or(());
ctx
.emit(CoreEvent::InvalidateQuery(ClientQuery::JobGetHistory))
ctx.emit(CoreEvent::InvalidateQuery(ClientQuery::JobGetHistory))
.await;
break;
}

View file

@ -47,8 +47,7 @@ impl CoreController {
pub async fn query(&self, query: ClientQuery) -> Result<CoreResponse, CoreError> {
// a one time use channel to send and await a response
let (sender, recv) = oneshot::channel();
self
.query_sender
self.query_sender
.send(ReturnableMessage {
data: query,
return_sender: sender,
@ -60,8 +59,7 @@ impl CoreController {
pub async fn command(&self, command: ClientCommand) -> Result<CoreResponse, CoreError> {
let (sender, recv) = oneshot::channel();
self
.command_sender
self.command_sender
.send(ReturnableMessage {
data: command,
return_sender: sender,
@ -87,8 +85,7 @@ pub struct CoreContext {
impl CoreContext {
pub fn spawn_job(&self, job: Box<dyn Job>) {
self
.internal_sender
self.internal_sender
.send(InternalEvent::JobIngest(job))
.unwrap_or_else(|e| {
println!("Failed to spawn job. {:?}", e);
@ -227,7 +224,9 @@ impl Core {
} else {
for library in self.state.libraries.iter() {
// init database for library
match library::loader::load(&ctx, &library.library_path, &library.library_uuid).await {
match library::loader::load(&ctx, &library.library_path, &library.library_uuid)
.await
{
Ok(library) => println!("Loaded library: {:?}", library),
Err(e) => println!("Error loading library: {:?}", e),
}
@ -313,12 +312,16 @@ impl Core {
file::explorer::open::open_dir(&ctx, &location_id, &path).await?,
),
ClientQuery::LibGetTags => todo!(),
ClientQuery::JobGetRunning => CoreResponse::JobGetRunning(self.jobs.get_running().await),
// TODO: FIX THIS
ClientQuery::JobGetHistory => CoreResponse::JobGetHistory(Jobs::get_history(&ctx).await?),
ClientQuery::GetLibraryStatistics => {
CoreResponse::GetLibraryStatistics(library::statistics::Statistics::calculate(&ctx).await?)
ClientQuery::JobGetRunning => {
CoreResponse::JobGetRunning(self.jobs.get_running().await)
}
// TODO: FIX THIS
ClientQuery::JobGetHistory => {
CoreResponse::JobGetHistory(Jobs::get_history(&ctx).await?)
}
ClientQuery::GetLibraryStatistics => CoreResponse::GetLibraryStatistics(
library::statistics::Statistics::calculate(&ctx).await?,
),
})
}
}

View file

@ -0,0 +1 @@

View file

@ -0,0 +1 @@

View file

@ -3,7 +3,8 @@ use futures::{channel::mpsc, SinkExt};
use serde::{Deserialize, Serialize};
use super::{
crdt::PoMethod, examples::tag::TagCreate, CrdtCtx, FakeCoreContext, PropertyOperation, SyncMethod,
crdt::PoMethod, examples::tag::TagCreate, CrdtCtx, FakeCoreContext, PropertyOperation,
SyncMethod,
};
pub struct SyncEngine {

View file

@ -50,7 +50,8 @@ static DOTFILE_NAME: &str = ".spacedrive";
// - accessible on from the local filesystem
// - already exists in the database
pub async fn check_location(path: &str) -> Result<DotSpacedrive, LocationError> {
let dotfile: DotSpacedrive = match fs::File::open(format!("{}/{}", path.clone(), DOTFILE_NAME)) {
let dotfile: DotSpacedrive = match fs::File::open(format!("{}/{}", path.clone(), DOTFILE_NAME))
{
Ok(file) => serde_json::from_reader(file).unwrap_or(DotSpacedrive::default()),
Err(e) => return Err(LocationError::DotfileReadFailure(e)),
};
@ -158,7 +159,9 @@ pub async fn create_location(ctx: &CoreContext, path: &str) -> Result<LocationRe
.create(
location::pub_id::set(uuid.to_string()),
vec![
location::name::set(Some(p.file_name().unwrap().to_string_lossy().to_string())),
location::name::set(Some(
p.file_name().unwrap().to_string_lossy().to_string(),
)),
location::is_online::set(true),
location::local_path::set(Some(path.to_string())),
],
@ -189,8 +192,7 @@ pub async fn create_location(ctx: &CoreContext, path: &str) -> Result<LocationRe
Err(e) => Err(LocationError::DotfileWriteFailure(e, path.to_string()))?,
}
ctx
.emit(CoreEvent::InvalidateQuery(ClientQuery::SysGetLocations))
ctx.emit(CoreEvent::InvalidateQuery(ClientQuery::SysGetLocations))
.await;
location

View file

@ -75,8 +75,8 @@ impl Volume {
let mut name = disk.name().to_str().unwrap_or("Volume").to_string();
let is_removable = disk.is_removable();
let file_system =
String::from_utf8(disk.file_system().to_vec()).unwrap_or_else(|_| "Err".to_string());
let file_system = String::from_utf8(disk.file_system().to_vec())
.unwrap_or_else(|_| "Err".to_string());
let disk_type = match disk.type_() {
sysinfo::DiskType::SSD => "SSD".to_string(),
@ -84,7 +84,8 @@ impl Volume {
_ => "Removable Disk".to_string(),
};
if cfg!(target_os = "macos") && mount_point == "/" || mount_point == "/System/Volumes/Data"
if cfg!(target_os = "macos") && mount_point == "/"
|| mount_point == "/System/Volumes/Data"
{
name = "Macintosh HD".to_string();
mount_point = "/".to_string();

View file

@ -1,5 +1,5 @@
# Core view
The primary screen in the Spacedrive app is of your entire virtual network, every "core" is a device under your full command. It is presented in a large panel list view, featuring bold visuals and quick interactions with your fleet.
Recent files, recent locations and settings are part of these panels, that can be customized at will.

View file

@ -1,22 +1,26 @@
# Roadmap
**Complete (Still Testing):**
- **File discovery** - Scan devices, drives and cloud accounts to build a directory of all files with metadata.
- **Preview generation** - Auto generate lower resolution stand-ins for image and video.
- **Statistics** - Total capacity, index size, preview media size, free space etc.
**In progress:**
- **File Explorer** - Browse online/offline storage locations, view files with metadata, perform basic CRUD.
- **Realtime synchronization** - Data index synchronized in realtime between devices, prioritizing peer-to-peer LAN connections (WiFi sync).
- **Self hosted** - Spacedrive can be deployed as a service, behaving as just another device powering your personal cloud.
**To be developed (MVP):**
- **Photos** - Photo and video albums similar to Apple/Google photos.
- **Search** - Deep search into your filesystem with a keybind, including offline locations.
- **Tags** - Define routines on custom tags to automate workflows, easily tag files individually, in bulk and automatically via rules.
- **Extensions** - Build tools on top of Spacedrive, extend functionality and integrate third party services. Extension directory on [spacedrive.com/extensions](/extensions).
**To be developed (Post-MVP):**
- **Spacedrive Cloud** - We'll host an always-on cloud device for you, with pay-as-you-go plans for storage.
- **Cloud integration** - Index & backup to Apple Photos, Google Drive, Dropbox, OneDrive & Mega + easy API for the community to add more.
- **Encrypted vault(s)** - Effortlessly manage & encrypt sensitive files, built on top of VeraCrypt. Encrypt individual files or create flexible-size vaults.

View file

@ -9,7 +9,7 @@
"db:migrate": "pnpm core prisma migrate dev",
"db:gen": "pnpm core prisma generate",
"lint": "turbo run lint",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"format": "prettier --write \"**/*.{ts,tsx,html,scss,json,yml,md}\"",
"desktop": "pnpm --filter @sd/desktop --",
"mobile": "pnpm --filter @sd/mobile -- ",
"web": "pnpm --filter @sd/web -- ",
@ -23,6 +23,7 @@
"typecheck": "pnpm -r exec tsc"
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^3.2.0",
"prettier": "^2.6.2",
"turbo": "^1.2.4"
},

View file

@ -1,11 +1,11 @@
import { ClientCommand, ClientQuery, CoreResponse } from '@sd/core';
import { EventEmitter } from 'eventemitter3';
import {
useMutation,
useQuery,
UseMutationOptions,
UseQueryOptions,
UseQueryResult,
UseMutationOptions
useMutation,
useQuery
} from 'react-query';
// global var to store the transport TODO: not global :D

View file

@ -1,7 +1,8 @@
import { useQuery } from 'react-query';
import { useState } from 'react';
import { useFileExplorerState } from './state';
import { useQuery } from 'react-query';
import { useBridgeCommand, useBridgeQuery } from '../bridge';
import { useFileExplorerState } from './state';
// this hook initializes the explorer state and queries the core
export function useFileExplorer(initialPath = '/', initialLocation: number | null = null) {

View file

@ -53,7 +53,6 @@
"zustand": "^3.7.2"
},
"devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^3.2.0",
"@types/babel-core": "^6.25.7",
"@types/byte-size": "^8.1.0",
"@types/lodash": "^4.14.182",

View file

@ -4,8 +4,11 @@ import ProgressBar from '../primitive/ProgressBar';
import { Transition } from '@headlessui/react';
import clsx from 'clsx';
const MiddleTruncatedText = ({ children, ...props }: DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>) => {
const text = children?.toString() ?? "";
const MiddleTruncatedText = ({
children,
...props
}: DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>) => {
const text = children?.toString() ?? '';
const first = text.substring(0, text.length / 2);
const last = text.substring(first.length);
@ -16,11 +19,29 @@ const MiddleTruncatedText = ({ children, ...props }: DetailedHTMLProps<HTMLAttri
return (
<div className="whitespace-nowrap overflow-hidden w-full">
<span {...props} style={{ maxWidth: `calc(100% - (1em * ${endWidth}))`, minWidth: startWidth }} className={clsx(props?.className, "text-ellipsis inline-block align-bottom whitespace-nowrap overflow-hidden")}>{first}</span>
<span {...props} style={{ maxWidth: `calc(100% - (1em * ${startWidth}))`, direction: "rtl" }} className={clsx(props?.className, "inline-block align-bottom whitespace-nowrap overflow-hidden")}>{last}</span>
<span
{...props}
style={{ maxWidth: `calc(100% - (1em * ${endWidth}))`, minWidth: startWidth }}
className={clsx(
props?.className,
'text-ellipsis inline-block align-bottom whitespace-nowrap overflow-hidden'
)}
>
{first}
</span>
<span
{...props}
style={{ maxWidth: `calc(100% - (1em * ${startWidth}))`, direction: 'rtl' }}
className={clsx(
props?.className,
'inline-block align-bottom whitespace-nowrap overflow-hidden'
)}
>
{last}
</span>
</div>
)
}
);
};
export default function RunningJobsWidget() {
const { data: jobs } = useBridgeQuery('JobGetRunning');
@ -39,7 +60,9 @@ export default function RunningJobsWidget() {
>
<div key={job.id} className="flex flex-col px-2 pt-1.5 pb-2 bg-gray-700 rounded">
{/* <span className="mb-0.5 text-tiny font-bold text-gray-400">{job.status} Job</span> */}
<MiddleTruncatedText className="mb-1.5 text-gray-450 text-tiny">{job.message}</MiddleTruncatedText>
<MiddleTruncatedText className="mb-1.5 text-gray-450 text-tiny">
{job.message}
</MiddleTruncatedText>
<ProgressBar value={job.completed_task_count} total={job.task_count} />
</div>
</Transition>

View file

@ -32,7 +32,6 @@ const Heading: React.FC<{ className?: string; children: string }> = ({ children,
export const SettingsScreen: React.FC<{}> = () => {
return (
<div className="flex flex-row w-full">
<div className="h-full border-r border-gray-100 w-60 dark:border-gray-550">
<div data-tauri-drag-region className="w-full h-7" />
<div className="p-5 pt-0">

View file

@ -3,7 +3,9 @@ button {
@apply cursor-default;
}
body { font-family: "InterVariable", sans-serif; }
body {
font-family: 'InterVariable', sans-serif;
}
.no-scrollbar {
-ms-overflow-style: none; /* for Internet Explorer, Edge */
@ -51,14 +53,13 @@ body { font-family: "InterVariable", sans-serif; }
width: 8px;
}
&::-webkit-scrollbar-track {
@apply bg-transparent rounded-[6px] my-[10px]
@apply bg-transparent rounded-[6px] my-[10px];
}
&::-webkit-scrollbar-thumb {
@apply rounded-[6px] bg-gray-300 dark:bg-gray-550;
}
}
@keyframes fadeIn {
from {
opacity: 0;
@ -98,7 +99,6 @@ body { font-family: "InterVariable", sans-serif; }
}
}
.dialog-overlay[data-state='open'] {
animation: fadeIn 200ms ease-out forwards;
}
@ -106,8 +106,8 @@ body { font-family: "InterVariable", sans-serif; }
animation: fadeIn 200ms ease-out forwards;
}
.dialog-content[data-state='open'] {
-webkit-animation: slide-top 0.3s cubic-bezier(0.215, 0.610, 0.355, 1.000) both;
animation: slide-top 0.3s cubic-bezier(0.215, 0.610, 0.355, 1.000) both;
-webkit-animation: slide-top 0.3s cubic-bezier(0.215, 0.61, 0.355, 1) both;
animation: slide-top 0.3s cubic-bezier(0.215, 0.61, 0.355, 1) both;
}
.dialog-content[data-state='closed'] {
animation: bounceDown 100ms ease-in forwards;

View file

@ -1,5 +1,5 @@
import React from 'react';
import clsx from 'clsx';
import React from 'react';
const sizes = {
default: 'py-1 px-3 text-md font-medium',

View file

@ -1,7 +1,8 @@
import React from 'react';
import { Menu } from '@headlessui/react';
import { ChevronDownIcon } from '@heroicons/react/solid';
import clsx from 'clsx';
import React from 'react';
import { Button } from './Button';
type Section = {

View file

@ -25,7 +25,6 @@
background-position: center;
}
.fade-in-image {
animation: fadeIn 1s;
-webkit-animation: fadeIn 1s;
@ -34,26 +33,46 @@
-ms-animation: fadeIn 1s;
}
@keyframes fadeIn {
0% {opacity:0;}
100% {opacity:1;}
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-moz-keyframes fadeIn {
0% {opacity:0;}
100% {opacity:1;}
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-webkit-keyframes fadeIn {
0% {opacity:0;}
100% {opacity:1;}
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-o-keyframes fadeIn {
0% {opacity:0;}
100% {opacity:1;}
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-ms-keyframes fadeIn {
0% {opacity:0;}
100% {opacity:1;}
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

View file

@ -4,12 +4,14 @@ importers:
.:
specifiers:
'@trivago/prettier-plugin-sort-imports': ^3.2.0
prettier: ^2.6.2
turbo: ^1.2.4
zustand: ^3.7.2
dependencies:
zustand: 3.7.2
devDependencies:
'@trivago/prettier-plugin-sort-imports': 3.2.0_prettier@2.6.2
prettier: 2.6.2
turbo: 1.2.4
@ -2178,7 +2180,6 @@ packages:
/@types/prop-types/15.7.5:
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
dev: true
/@types/qs/6.9.7:
resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==}
@ -2239,7 +2240,6 @@ packages:
'@types/prop-types': 15.7.5
'@types/scheduler': 0.16.2
csstype: 3.0.11
dev: true
/@types/responselike/1.0.0:
resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==}
@ -2249,7 +2249,6 @@ packages:
/@types/scheduler/0.16.2:
resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==}
dev: true
/@types/serve-static/1.13.10:
resolution: {integrity: sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==}