Skip to content

Documents

Textile Notes

Documents come in many different formats and rely on many different standards. Textile remains flexible enough for your application to write or read any document your user wants to store. Below, we walk through how to think about each of these cases generally. Then we show an example of building on the popular note storage schema used Slate and all the note-taking apps that use it.

Get Started

Document connectors are use-case specific. However, there are many cases where applications want to store PDFs or other formats for their users. These often fall into specific connectors (e.g., purchasing or receipts for PDFs). Let's look quickly at how you can leverage Textile to connect to one of the popular notes formats used by many apps. We are going to jump right in, so if any of the below does not sound familiar, be sure to read over the Tour of Textile.

The Slate Notes Schema

We are focusing on the note storage schema used by Slate. The schema is simply this,

{
  "document": Object,
  "blocks": Object,
  "inlines": Object,
  "rules": Array,
}

And so may result in a document that looks more like this,

{
  "document": {
    "nodes": [
      {
        "match": { "type": "paragraph" }
      }
    ]
  },
  "blocks": {
    "list": {
      "nodes": [{
        "match": { "type": "item" }
      }]
    },
    "item": {
      "parent": { "type": "list" }
    }
  },
  "inlines": {
    "emoji": {
      "isVoid": true,
      "nodes": [{
        "match": { "object": "text" }
      }]
    }
  }
}

Any application using the Slate library is already using a variant of the schema shown above and so can store a user's notes (or other documents) in a way that other apps can make use of them (new UI, collaborative interfaces, etc.).

Slate thread schema

The first thing we need to do is take the above Slate schema for documents and format it as a Textile JSON schema. Here is what that looks like, with each of the primary elements in the Slate document defined as properties of the JSON object.

{
  "name": "slatejs",
  "mill": "/json",
  "plaintext": true,
  "pin": true,
  "json_schema": {
    "$id": "https://example.com/slatejs.schema.json",
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "Hash Optimized Slate.js Schema",
    "description": "Slate.js Schema Files.",
    "required": [],
    "type": "object",
    "properties": {
      "document": {
        "type": "object"
      },
      "blocks": {
        "type": "object"
      },
      "inlines": {
        "type": "object"
      },
      "rules": {
        "type": "array"
      }
    }
  }
}

We can save that JSON file as slate.json to use for creating a thread below.

Create a Slate thread

You can now use the above schema to quickly create Textile threads that are interoperable with other apps using the Slate library for document editing.

Here's how we create our app's new thread.

textile threads add "app notes" --schema-file=slate.json --type="public" --sharing="invite_only"
const schema = require('slate.json')
await textile.threads.add("app notes", JSON.stringify(schema), "your.bundle.id.version.Notes", "public", "invite_only")
const schema = require('slate.json');
const threadKey = 'your.bundle.id.version.Notes'
const threadName = 'app notes'
const schema = {
  id: '',
  json: JSON.stringify(schema),
  preset: AddThreadConfig.Schema.Preset.NONE
}
const config = {
  key: threadKey,
  name: threadName,
  type: Thread.Type.PUBLIC,
  sharing: Thread.Sharing.INVITE_ONLY,
  schema: schema,
  force: false,
  members: []
}
const newTarget = await textile.threads.add(config)
NSError *error;
AddThreadConfig_Schema *schema = [[AddThreadConfig_Schema alloc] init];
schema.json = slateStringJSON;
AddThreadConfig *config = [[AddThreadConfig alloc] init];
config.key = @"your.bundle.id.version.Notes";
config.name = @"app notes";
config.type = Thread_Type_Public;
config.sharing = Thread_Sharing_InviteOnly;
config.schema = schema;
Thread *thread = [Textile.instance.threads add:config error:&error];
if (error) {
  // Do something with this error
} else {
  // Success!
}
var error: NSError?
let schema = AddThreadConfig_Schema()
schema.json = slateStringJSON
let config = AddThreadConfig()
config.key = "your.bundle.id.version.Notes"
config.name = "app notes"
config.type = Thread_Type.public
config.sharing = Thread_Sharing.inviteOnly
config.schema = schema
let thread = Textile.instance().threads.add(config, error: &error)
if (error != nil) {
  // Do something with this error
} else {
  // Success!
}
@todo

Public notes

The schema above used the plaintext: true option, meaning that all each note shared to a thread will not be encrypted. This can be useful for interoperability, giving you ways to allow your user to open their documents in apps not connected to Textile.

If your app requires fully private notes, remove this option, or set it to false

Adding new notes

Here, let's look at how a Slate document can be converted into JSON and stored in our thread.

const title = "Note Title"
const json = slateNote.toJSON()
const block = await textile.files.add(json, title, "12D3KooWSYT0SUX7f415pwjHSVUsuymnixmRtPGySmFYtWE51z8")'

Using Slate's built-in JSON converter, you can extract a JSON document from your users live notes and store them in a Textile thread.

Connect to existing photo threads

If your app can display Slate notes, you can now request access to other apps that are using the Slate schema and display a user's other notes in your app.

Cafe Sync & Recovery

A critical component of the image & media connector is the ability for your users to recover their data in the future. Threads can be easily backed up by registering your app with a live cafe or by encouraging your users to manage their cafe subscriptions.

When a user joins your app, either new or by linking their existing Textile wallet, you can provide a cafe for app-specific thread storage. Read our instructions on Cafe setup or try out our developer instances immediately.

Apps & demos

There are a few apps that are using document connector already. The Textile Notes mobile and desktop apps are two. You can also browse the source code for both of those apps to understand how they connect to and create a user's photo streams. Another up and coming document supporting app to check out is the Epona app.