? Editing: Post:21.body Save Delete Cancel
Content changed Sign & Publish new content

ZeroBlog

Demo for decentralized, self publishing blogging platform.

Follow in NewsfeedFollowing

Latest comments:

Add new post

Title

21 hours ago · 2 min read ·
3 comments
Body
Read more

Not found

ZeroChat tutorial (new)

on Dec 14, 2016 · 9 min read

In this tutorial we going to build a P2P, decentralized, server and backend-less chat site in less then 100 lines of code.
(This is a simplified and pure-javascript rework of the original tutorial.)


Creating new site

  • Click on ⋮ > “Create new, empty site” menu item on the site ZeroHello.
  • You will be redirected to a completely new site that is only modifiable by you!
  • Drag the top-right “0” button to left to show the sidebar
  • At the bottom change the Site title to “My ZeroChat tutorial”, then press “Save site settings”.

The chat site’s HTML code

  • Open “data/[yoursiteaddress]/index.html” file in you favorite editor.
  • Change the <body> tag’s content to:
<body>

<a href="#Select+user" id="select_user" onclick='return page.selectUser()'>Select user</a>:
<input type="text" id="message">
<input type="button" id="send" value="Send!" onclick="return page.sendMessage()"/>
<ul id="messages">
 <li>Welcome to ZeroChat!</li>
</ul>
<script type="text/javascript" src="js/ZeroFrame.js"></script>

</body>

The js/ZeroFrame.js file (automatically bundled if you create your site using ZeroHello) contains the ZeroFrame class that allows us to communicate with the websocket based ZeroFrame API.

First ZeroFrame API call

  • Initialize our application in a <script> block, after the ZeroFrame.js include:
<script type="text/javascript" src="js/ZeroFrame.js"></script>

<script>
class ZeroChat extends ZeroFrame {
    addMessage (username, message) {
        var message_escaped = message.replace(/</g, "&lt;").replace(/>/g, "&gt;")  // Escape html tags in the message
        this.messages.innerHTML += "<li><b>" + username + "</b>: " + message_escaped + "</li>"
    }

    onOpenWebsocket () {
        this.messages = document.getElementById("messages")
        this.addMessage("System", "Ready to call ZeroFrame API!")
    }
}

page = new ZeroChat()
</script>
  • If we reload the page we should see a “Ready to call ZeroFrame API!” message.
  • To make the “Select User” button display the user select dialog add the following function to the ZeroChat class:
    selectUser () {
        this.cmd("certSelect", {accepted_domains: ["zeroid.bit"]})
        return false
    }

Display user’s current ZeroID account

When something changed that is affects the site (new content arrived, user changed, etc.) a websocket event will be pushed to your browser.
(the format is same as you query siteInfo command)

  • To handle this event add this to our class:
    onRequest (cmd, message) {
        if (cmd == "setSiteInfo") {
            if (message.params.cert_user_id)
                document.getElementById("select_user").innerHTML = message.params.cert_user_id
            else
                document.getElementById("select_user").innerHTML = "Select user"
            this.site_info = message.params  // Save site info data to allow access it later
        }
    }

This code will real-time update the currently selected user name.

  • To also display the currently selected username when the page loads add this to “onOpenWebsocket” function:
        this.cmd("siteInfo", {}, (site_info) => {
            if (site_info.cert_user_id)
                document.getElementById("select_user").innerText = site_info.cert_user_id
            this.site_info = site_info
        })

Now our application should always display the currently selected user correctly. (Even if its modified from other browser window)

Setting user content permissions

To allow other users to post on our site we have to define the rules of the third-party content.

Create a data/users/content.json file in your site’s directory:

{
  "files": {},
  "ignore": ".*",
  "modified": 0.0,
  "signs": {},
  "user_contents": {
    "cert_signers": {
      "zeroid.bit": [ "1iD5ZQJMNXu43w1qLB8sfdHVKppVMduGz" ]
    },
    "permission_rules": {
      ".*": {
        "files_allowed": "data.json",
        "max_size": 10000
      },
      "bitmsg/.*@zeroid.bit": { "max_size": 15000 }
    },
    "permissions": {
      "bad@zeroid.bit": false,
      "nofish@zeroid.bit": { "max_size": 100000 }
    }
  }
}
  • "ignore": ".*": The files in this directory will be signed by the users and not by the site’s owner.
  • cert_signers: We accept *@zeroid.bit users and they have to come with a cert that is has to signed by 1iD5ZQJMNXu43w1qLB8sfdHVKppVMduGz address.
  • permission_rules: We give 10kbytes of space to every user (15kb if registered using bitmessage)
  • permissions: Per-user permissions: ban “bad@zeroid.bit” user and allow 100k storage to “nofish@zeroid.bit” user. ( it's me :) )

After we saved this file we also have to modify our site’s root content.json to ignore everything in this directory on signing and load the file containing the rules:

  ...
    "ignore": "data/.*",
    "includes": {
        "data/users/content.json": {
            "signers": [],
            "signers_required": 1
        }
    },
  ...

Note: You can give moderation permissions to other users by adding addresses to “signers” list.

  • Sign the root content.json modifications by pressing the “Sign” button on the sidebar.
  • Then keep the sidebar open and change “content.json” to “data/users/content.json” and press the “Sign” button again!

Adding messages to our json file

When hitting the Send button we going to add the message to our user’s data.json file, sign it, then publish it to other users.

  • Create a new function in ZeroChat class:
    sendMessage () {
        if (!this.site_info.cert_user_id) {  // No account selected, display error
            this.cmd("wrapperNotification", ["info", "Please, select your account."])
            return false
        }

        // This is our data file path
        var data_inner_path = "data/users/" + this.site_info.auth_address + "/data.json"
        var content_inner_path = "data/users/" + this.site_info.auth_address + "/content.json"

        // Load our current messages
        this.cmd("fileGet", {"inner_path": data_inner_path, "required": false}, (data) => {
            if (data)  // Parse current data file
                data = JSON.parse(data)
            else  // Not exists yet, use default data
                data = { "message": [] }

            // Add the new message to data
            data.message.push({
                "body": document.getElementById("message").value,
                "date_added": Date.now()
            })

            // Encode data array to utf8 json text
            var json_raw = unescape(encodeURIComponent(JSON.stringify(data, undefined, '\t')))

            // Write file to disk
            this.cmd("fileWrite", [data_inner_path, btoa(json_raw)], (res) => {
                if (res == "ok") {
                    // Reset the message input
                    document.getElementById("message").value = ""
                    // Sign the changed file in our user's directory
                    this.cmd("siteSign", {"inner_path": content_inner_path}, (res) => {
                        // Publish to other users
                        this.cmd("sitePublish", {"inner_path": content_inner_path, "sign": false})
                    })
                } else {
                    this.cmd("wrapperNotification", ["error", "File write error: #{res}"])
                }
            })
        })

        return false
    }
  • After this modification type something to the message input and press the Send button! You should see the message in the data/users/[your auth address]/data.json file.

    (Don’t worry if you see “Publish failed” message: it is normal, since we don’t have any other users on our site yet)

Creating database

Now we can save and publish our messages to other users, let’s display it in our application! The best way to do this is map all data.json files to an SQL database.

The ZeroNet automatically do this for you, all you need is a dbschema.json file in your site’s directory that describe your table structure:

{
    "db_name": "ZeroChat",
    "db_file": "data/zerochat.db",
    "version": 2,
    "maps": {
        "users/.+/data.json": {
            "to_table": [ "message" ]
        },
        "users/.+/content.json": {
            "to_json_table": [ "cert_user_id" ],
            "file_name": "data.json"
        }
    },
    "tables": {
        "json": {
            "cols": [
                ["json_id", "INTEGER PRIMARY KEY AUTOINCREMENT"],
                ["directory", "TEXT"],
                ["file_name", "TEXT"],
                ["cert_user_id", "TEXT"]
            ],
            "indexes": ["CREATE UNIQUE INDEX path ON json(directory, file_name)"],
            "schema_changed": 10
        },
        "message": {
            "cols": [
                ["body", "TEXT"],
                ["date_added", "INTEGER"],
                ["json_id", "INTEGER REFERENCES json (json_id)"]
            ],
            "indexes": ["CREATE UNIQUE INDEX message_key ON message(json_id, date_added)"],
            "schema_changed": 10
        }
    }
}
  • "db_name": "ZeroChat": Used only for debugging
  • "db_file": "data/zerochat.db": The SQLite database file will be stored here
  • "version": 2: Define the json table structure, version 2 is better suited to ZeroID based sites. More info in the reference docs.
  • "maps": {: Describes the json files -> table conversion
  • "users/.+/data.json": { "to_table": [ "message" ] }: Put the data from every user's data.json file message node to message table.
  • "users/.+/content.json": { "to_json_table": [ "cert_user_id" ], "file_name": "data.json"}: For easy SQL Join store the username in the data.json file's json table entry.
  • "tables": {: Describe the tables and indexing structure. A json table entry will be created automatically for every json file.
  • ["json_id", "INTEGER REFERENCES json (json_id)"]: Every table should contain a json_id column, it defines the source file path.
  • "schema_changed": 10: Increment this when you change the table structure, so the peers can drop the table and re-create it from the json files.

Tip: For the best performance always create an index for json_id column in your tables, because when new file arrives the data will be updated based on this column.

  • Press the Reload, then the Rebuild button on the sidebar to generate the database.

If you did everything well, then the data/zerochat.db SQLite file will be created. To browse these files I recommend using SQLiteStudio (it’s free and opensource)

Displaying messages

The messages are loaded to the SQL database, so we can easily query them using the dbQuery command:

    loadMessages () {
        this.cmd("dbQuery", ["SELECT * FROM message LEFT JOIN json USING (json_id) ORDER BY date_added DESC"], (messages) => {
            document.getElementById("messages").innerHTML = ""  // Always start with empty messages
            for (var i=0; i < messages.length; i++) {
                this.addMessage(messages[i].cert_user_id, messages[i].body)
            }
        })
    }

Add this.loadMessages() to onOpenWebsocket function, then reload the page and you should see the messages you typed in.

To make it “real time” and display new messages immediately as they come in you also have to add the this.loadMessages() to the onRequest function:

    onRequest (cmd, message) {
        if (cmd == "setSiteInfo") {
            if (message.params.cert_user_id)
                document.getElementById("select_user").innerHTML = message.params.cert_user_id
            else
                document.getElementById("select_user").innerHTML = "Select user"
            this.site_info = message.params  // Save site info data to allow access it later

            // Reload messages if new file arrives
            if (message.params.event[0] == "file_done")
                this.loadMessages()
        }
    }

Also reload the data when we submit a new message:

    sendMessage () {
        ...
                    // Sign the changed file in our user's directory
                    this.cmd("siteSign", {"inner_path": content_inner_path}, (res) => {
                        this.loadMessages() // Reload messages
                        ...
        ...

That’s it! Now the messages are updated in real-time! You can try it by opening an another browser window and enter a messages there.

Final touches

  • Send messages by pressing enter
<input type="text" id="message" onkeypress="if (event.keyCode == 13) page.sendMessage()">
  • And add some CSS style to make it look better
<style>
* { font-family: monospace; line-height: 1.5em; font-size: 13px; vertical-align: middle; }
body { background-color: white; }
input#message { padding: 5px; width: 50%;  }
input#send { height: 34px; margin-left: -2px; }
ul { padding: 0px; }
li { list-style-type: none; border-top: 1px solid #eee; padding: 5px 0px; }
li:nth-child(odd) { background-color: #F9FAFD; }
li b { color: #3F51B5; }
</style>

Congratulations! You have completed the ZeroChat tutorial! :)

Some idea for improvements:

  • Display message time
  • Move source code to separate .js file
  • Limit displayed messages / add paging
  • Markdown formatting
  • Username mention

Tip: The .js files are cached. To avoid it you need to keep open the Dev Console (F12) with "Disable cache" checked.

Tip: Don't forget to re-sign and publish your site if you do any modification on the source code.

Tip: Your site's private key is in data/users.json file (search for your site's address, then there will be a privatekey entry), so it's a good idea to backup it!

Tip: ZeroNet has a built-in .js and .css merging feature for developers. To enable it add debug to zeronet.conf file's [global] section, then it will response every file's content in the directory if you request all.js or all.css

69 Comments:

user_name1 day ago
Reply
Body
zeronetdnson Nov 21, 2018
Reply

Free Slow Zeronet through Domain Name Server.

http://127.0.0.1:43110/1uPLoaDwKzP6MCGoVzw48r4pxawRBdmQc/data/users/19eE8Tr5u2FgXTCZoAZz81p6yoBxcpoaiz/Zeronet-through-Dns-Tunnel-missing-zeronet-dns-tunnel-site-dns_server-ip-list.zip

its possible with Github: Dnsscapy and requirements Scapy and Npcap.
Which are in that file in ZeroUp.
missing a way to publish DnsScapy Server ip list for DnsScapy Clients which is encripted and its a point click and the DnsScapy Client is then connected to ZeroNet for free and slow(bandwith of dns limitation mean it does not stress the system) ZeroNet,
automatic registration of dynamic ip code is missing.

blurhyon Aug 11, 2018
Reply

leftside: That's inefficient regarding disk space, isn't it????

yes,but it's efficient to query data

leftsideon Aug 11, 2018
Reply

blurhy: yes

That's inefficient regarding disk space, isn't it????

blurhyon Aug 11, 2018
Reply

leftside: @nofish @binchan @blurHY So, it means data.json & zerochat.db are duplicates????

yes

leftsideon Aug 11, 2018
Reply

sameer: automatic data.json to sql mapping is cool, except I am not in to JS.

@nofish @binchan @blurHY So, it means data.json & zerochat.db are duplicates????

sameeron Jun 26, 2018
Reply

automatic data.json to sql mapping is cool, except I am not in to JS.

maxizrinon Jun 07, 2018
Reply

Very nice, thank you!

jamesrayon Dec 30, 2017
Reply

jamesray: Posting this to get a link for the comment.

Alas, this link doesn't seem to work.

jamesrayon Dec 30, 2017
Reply

jamesray: I went through this procedure twice with two different test sites, but ran into the same issues.
this.loadMessages() //Contrary to as claimed, after adding this and reloading the page, I did not see the messages that I typed in, although they were in the data.json file, and data/zerochat.db was added.
// Reload messages if new file arrives. Adding this causes the selected user, e.g. jamesray@zeroid.bit, to change to "Select user", and sent messages are then not recorded in the log data.json file in /users/address
if (message.params.event[0] == "file_done")
this.loadMessages()This is the zipped folder of a site after trying to follow this tutorial:https://drive.google.com/file/d/1LfariziZ2xFIhfvcHRsMGfNHdkNd3dNG/view?usp=sharing

Posting this to get a link for the comment.

jamesrayon Dec 30, 2017
Reply

I went through this procedure twice with two different test sites, but ran into the same issues.

this.loadMessages() //Contrary to as claimed, after adding this and reloading the page, I did not see the messages that I typed in, although they were in the data.json file, and data/zerochat.db was added.

// Reload messages if new file arrives. Adding this causes the selected user, e.g. jamesray@zeroid.bit, to change to "Select user", and sent messages are then not recorded in the log data.json file in /users/address if (message.params.event[0] == "file_done") this.loadMessages()
This is the zipped folder of a site after trying to follow this tutorial:
https://drive.google.com/file/d/1LfariziZ2xFIhfvcHRsMGfNHdkNd3dNG/view?usp=sharing

littlelittleon Oct 16, 2017
Reply

mark

pangeaon Oct 07, 2017
Reply

nice for study zeroFrame and db connection, thanks!

alvinzhanon Oct 01, 2017
Reply

greate, it's cool~

3md9s01on Jul 20, 2017
Reply

Thanks!! o(^∀^*)o

wxlon May 23, 2017
Reply

cool

jupadron May 07, 2017
Reply

Awesome tutorial! Thank you very much :)

185185on Mar 09, 2017
Reply

how to get username in javascript?

tozeredolsantoson Jan 18, 2017
Reply

downlad games

tester999on Jan 13, 2017
Reply

Never mind I moved the files into a new site and it started to work again? Odd.

tester999on Jan 12, 2017
Reply

OK I reworked your example into a website search engine, but now the 0 in the top right corner stopped working. the user login button stopped to. I guessing I did something stupid but any ideas?

tester999on Jan 11, 2017
Reply

@Klew
I think you would just make a static .json file then map it with a dbschema.json

klewon Jan 11, 2017
Reply

Do you know how to make a static database for a zite?

nofishon Jan 11, 2017
Reply

tester999: OK I get it now, you make changes to the dbschema.json, then click the "reload" button, then "rebuild" button to rebuild the sqlite database. What if you wanted to add a SQL view to your database?

I have not tried, but you can add any kind of SQL commands to the "indexes" array in the table specification.

tester999on Jan 11, 2017
Reply

OK I get it now, you make changes to the dbschema.json, then click the "reload" button, then "rebuild" button to rebuild the sqlite database. What if you wanted to add a SQL view to your database?

tester999on Jan 11, 2017
Reply

OK the error messages it's giving me are "Internal error: OperationalError: no such table: main.message
UiWebsocket.py line 99 > UiWebsocket.py line 184 > SidebarPlugin.py line 616 > SiteStorage.py line 112 > Db.py line 208 > DbCursor.py line 109 > DbCursor.py line 99 > DbCursor.py line 53"

I'm not much of a python programmer, look sort of like C. I take it I should be looking at Zerobundle/ZeroNet/scr/db to understand what should be in a dbschema.json file?

tester999on Jan 09, 2017
Reply

OK I understand the code a little more. I was able to add a row to the message table, and get it to update. What are the rules round the dbschema.json file? Where could I go to learn more about how it's used?

tester999on Jan 03, 2017
Reply

OK I looked at ZeroTalk code. On line 1567 function submitTopicVote. I don't understand all your code yet. But it looks like it's mapping a json file to the database. Then the publish command somehow dose an update to the SQL database. All the tables have a json_id column used as a userID.

nofishon Jan 03, 2017
Reply

tester999: I tried to edit the comment of the other client in the database then post a new comment. It show up in my web bower, then disappeared are a few messages. Interesting, is it some type of message signing to prevent tampering?

You can modify any content on your local client, but you can't publish the modifications if you don't have the private key for the use.

How would you do an up vote system like in a reddit type site?

ZeroTalk has reddit like upvoting (not used for sorting yet, because it does not works well with small amount of users)

tester999on Jan 03, 2017
Reply

How would you do an up vote system like in a reddit type site?

tester999on Jan 03, 2017
Reply

I tried to edit the comment of the other client in the database then post a new comment. It show up in my web bower, then disappeared are a few messages. Interesting, is it some type of message signing to prevent tampering?

nofishon Jan 03, 2017
Reply

tester999: I see, what's to stop a malicious user from editing what other people have said; when the malicious user makes an update to the database?

In directory data/users/[user's publickey] directory the files are only modifiable if you have the private key for the [user's publickey]. This way you can only modify your own files.

tester999on Jan 03, 2017
Reply

nofish:
Only SELECT command supported, because in a P2P network you need to sign and verify every users data separately and it would be inefficient to do from database, so we sync the files and then update the database locally based on that data.

I see, what's to stop a malicious user from editing what other people have said; when the malicious user makes an update to the database?

nofishon Jan 03, 2017
Reply

tester999: But where is the "keyvalue" table created, and what is it for?

The keyvalue is an internal table (eg. it stores the version of the tables), usually you don't have to deal with that.

nofishon Jan 03, 2017
Reply

tester999: What is the difference between the update button and the publish button?

The update button cleans up the failed files and re-check the changes from other peers. The Publish button submits your version to other peers.

OK I found the private key in that file. What's the line "cert": "zeroid.bit", for? An empty site I made didn't have that line.

Multi-user sites works a bit differently: you need a certificate from an id provider to publish new content to the site.

I trying to understand how the JavaScript works. I can see what the code is doing, but it looks like some type of backend is do the SQL update statement. Could the SendMessage function be rewritten to have an SQL update statement?

Only SELECT command supported, because in a P2P network you need to sign and verify every users data separately and it would be inefficient to do from database, so we sync the files and then update the database locally based on that data.

tester999on Jan 03, 2017
Reply

I opened up the zerochat.db with "DB Browser for SQLite" I can see how the dbschema.json, make the tables "json" and "message", and the table "sqlite_sequence" is created by sqlite, but where is the "keyvalue" table created, and what is it for?

tester999on Jan 03, 2017
Reply

OK that update button did it the message is gone now. :) Thanks.
By the way both clients are using tor and show connected.

What is the difference between the update button and the publish button?

OK I found the private key in that file. What's the line "cert": "zeroid.bit", for? An empty site I made didn't have that line.

I trying to understand how the JavaScript works. I can see what the code is doing, but it looks like some type of backend is do the SQL update statement. Could the SendMessage function be rewritten to have an SQL update statement?

nofishon Dec 31, 2016
Reply

border0464fred: does he need to have the port 15441 open for publishing ?

It's not required, but recommended to have opened port or Tor: Available

If your port is closed and you have no Tor connection, then your first visitor must have an opened port and he/she may need to wait some minutes before the page displayed.

border0464fredon Dec 30, 2016
Reply

does he need to have the port 15441 open for publishing ?

nofishon Dec 30, 2016
Reply

tester999: never mind I got it working. The 2nd client was not the most current version of zero net. But it's still saying "missing file: content.json"

If you have correctly signed the latest version of your site, then pressing the update button on sidebar should remove the missing file.

Also how do you get the private key of a site you create from the UI?

Tip: Your site's private key is in data/users.json file (search for your site's address, then there will be a privatekey entry), so it's a good idea to backup it!

tester999on Dec 30, 2016
Reply

never mind I got it working. The 2nd client was not the most current version of zero net. But it's still saying "missing file: content.json" Also how do you get the private key of a site you create from the UI?

tester999on Dec 30, 2016
Reply

I have done the tutorial and got it working my my bowers, but I can't get other peers to see it. The control panel to the right show a missing file: content.json . I created a new site without changing anything, and go the same result. I;m using linux mint and firefox.

border0464fredon Dec 28, 2016
Reply

If im not using the GUI to create the site I have to find somewhere a version of ZeroFrame.js I trust and add it manually. Im totally ok with this but a checksum validation seem to be a good practice when you add libraries found on the internet.

@nofish
Would it be possible to have an official checksum from a zeronetDev ?
Do you need me to open a issue on github for this ?

border0464fredon Dec 25, 2016
Reply

Linux users can use sqlitebrowser to look at .db files

border0464fredon Dec 24, 2016
Reply

@nofish Thx for the tuto, by the amount of comments, I see people are following it closely :D


"The best way to do this is map all data.json files to an SQL database.
The ZeroNet automatically do this for you, all you need is a dbschema.json file in your site’s directory"

Can't we store content directly in a database instead of a .json file ? it seem like an extra step to
me.

Or what's the advantage to pass by a sqlite database instead of just loading the json ?

nofishon Dec 21, 2016
Reply

sidorex: thx and how can I trust that every user is sharing all the users/json-files? e.g. if all my 21 of 21 connections are all refusing to publish abc-users json-file, would I notice that?

No, you would not notice that, same thing with page updates: If everyone blocks it, then you won't get it.

sidorexon Dec 20, 2016
Reply

nofish: The database file is never got synced, but it's generated from .json files that are always signed by the owners.

thx and how can I trust that every user is sharing all the users/json-files? e.g. if all my 21 of 21 connections are all refusing to publish abc-users json-file, would I notice that?

nofishon Dec 20, 2016
Reply

12hlearn: your codes have es6 and es5 at the same time...WebStorm show many error or warring to me, and why not use es5 now?

This is not a javascript tutorial, so feel free to use the style that best suited to you

12hlearnon Dec 20, 2016
Reply

your codes have es6 and es5 at the same time...WebStorm show many error or warring to me, and why not use es5 now?

nofishon Dec 19, 2016
Reply

sidorex: hiho, how can I be sure that no one has manipuleted or is sending the wrong database/sql?

The database file is never got synced, but it's generated from .json files that are always signed by the owners.

sidorexon Dec 19, 2016
Reply

hiho, how can I be sure that no one has manipuleted or is sending the wrong database/sql?

nofishon Dec 19, 2016
Reply

eibriel: There is an error on the SQL command, should be:
SELECT * FROM message LEFT JOIN json USING (json_id) ORDER BY date_added DESC

Thanks, fixed

eibriel: And could be that this.loadMessages() should be inside (site_info) => {}?

It works both way: if it's outside, then it's executed in parallel, if inside, then sequential

eibrielon Dec 19, 2016
Reply

And could be that this.loadMessages() should be inside (site_info) => {}?

onOpenWebsocket () {
        this.messages = document.getElementById("messages")
        this.addMessage("System", "Ready to call ZeroFrame API!", "")

        this.cmd("siteInfo", {}, (site_info) => {
            if (site_info.cert_user_id)
                document.getElementById("select_user").innerText = site_info.cert_user_id
            this.site_info = site_info
            this.loadMessages()
        })
        //this.loadMessages()
    }
eibrielon Dec 19, 2016
Reply

There is an error on the SQL command, should be:

SELECT * FROM message LEFT JOIN json USING (json_id) ORDER BY date_added DESC
nofishon Dec 18, 2016
Reply

weakish:

  • Escape works differently

    > escape("helló")
    "hell%F3"
    > decodeURI("helló")
    "helló"
    ```
    it's necessary, because js can't convert utf8 to base64:
    ```js
    > btoa("✓")
    VM391:1 Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
      at <anonymous>:1:1
    ```
  • The var is probably not necessary there (not sure what happens if the callback returns with no result)

  • Yes, page is global

weakishon Dec 18, 2016
Reply

First, escape is depraved. (Replace it with decodeURI?).

Second,

            if (data)  // Parse current data file
                var data = JSON.parse(data)
            else  // Not exists yet, use default data
                var data = { "message": [] }

Does var here necessary? How about just data =without extra declaration?

Third, .page = new ZeroChat(). Where is page declared? Or is it global?

nekocrosson Dec 17, 2016
Reply

You can open the content.json file and add new keys the same way as you do for the data.json

Does it mean if I add a key in data/users/content.json, the key will appear in data/users/[new user's auth address]/content.json when new user submitting the first comment?

Oh,I know what I should do now.

nofishon Dec 17, 2016
Reply

nekocross: THX a lot.There are some questions still confuese me:
Who creates data/users/[user auth address]/content.json?

It created automatically by the user when submitting the first comment.

When will data/users/[user auth address]/data.json be signed?

it created automatically when you execute this.cmd("sitePublish", {"inner_path": inner_path}) (It signs the files in the directory by default, then publish to the network)

How to add 'optional' key in data/users/[user auth address]/data.json for new users automatically?

You can open the content.json file and add new keys the same way as you do for the data.json

nekocrosson Dec 17, 2016
Reply

THX a lot.
There are some questions still confuese me:
Who creates data/users/[user auth address]/content.json?
When will data/users/[user auth address]/data.json be signed?
How to add 'optional' key in data/users/[user auth address]/data.json for new users automatically?

12hstudyon Dec 17, 2016
Reply

Thanks

nofishon Dec 15, 2016
Reply

whacko: Would be cool to see a live demo of this!

The expected result is here: http://127.0.0.1:43110/1Ao2w61hpihHgCb44Tjbv7dCE3ifbaiscK

whackoon Dec 15, 2016
Reply

Would be cool to see a live demo of this!

nofishon Dec 14, 2016
Reply

p2p: github is down? maybe you can try a proxy or tor

There was a problem with github servers: https://status.github.com/

p2pon Dec 14, 2016
Reply

nofish: There was some drama around it, but it's good to hear they picked it up again.btw: github is down for me: "No server is currently available to service your request."

github is down? maybe you can try a proxy or tor

nofishon Dec 14, 2016
Reply

p2p: what do you mean Coffeescript is no longer developed?https://github.com/jashkenas/coffeescript/ Update 1.12.1 release date 6 days ago

There was some drama around it, but it's good to hear they picked it up again.
btw: github is down for me: "No server is currently available to service your request."

p2pon Dec 14, 2016
Reply

nofish: Coffeescript is no longer developed, so I would recommend JS, but it's depends on personal preference.

what do you mean Coffeescript is no longer developed?https://github.com/jashkenas/coffeescript/ Update 1.12.1 release date 6 days ago

nofishon Dec 14, 2016
Reply

p2p: THX! what do you recommend for future zite dev? JS or coffeescript?

Coffeescript is no longer developed, so I would recommend JS, but it's depends on personal preference.

p2pon Dec 14, 2016
Reply

THX! what do you recommend for future zite dev? JS or coffeescript?

greatsickon Dec 14, 2016
Reply

first send, execept nofish nz user!!!

sirenycon Dec 14, 2016
Reply

With each update the ZN is getting fucked! =)

This page is a snapshot of ZeroNet. Start your own ZeroNet for complete experience. Learn More