diff --git a/README.md b/README.md new file mode 100644 index 0000000..9afa6a9 --- /dev/null +++ b/README.md @@ -0,0 +1,84 @@ +twister-html +============ + +HTML interface for [Twister](http://twister.net.co). +To use it, clone this repo under ~/.twister/html like this: + + git clone https://github.com/miguelfreitas/twister-html.git ~/.twister/html + +Localisation +------------ + +If you want a localised interface (currently available only for NL, IT, FR and soon RU), +use the experimental `i18n` branch: + + git checkout i18n + +If you want to translate it in your own language, check [these instructions](#translations) + +Contribute +---------- + +Feel free to fork and send pull requests! +To make it easier for us to accept your patches, please follow the conventional +GitHub workflow: + + # after forking, clone your repo + rm -rf ~/.twister/html + git clone git@github.com:yournickname/twister-html.git ~/.twister/html + cd ~/.twister/html + # CREATE A NEW BRANCH, specific to the fix you're implementing + git checkout -b my-fix + # ... make your changes ... + # commit and push + git commit -m "Fixing #1234 - bad foobarizer" && git push + # Now open a pull request from branch my-fix to miguelfreitas:master on github. + # Once the request is accepted, switch back to master and track upstream + git remote add upstream https://github.com/miguelfreitas/twister-html.git # one-off setup + git fetch upstream + git checkout master + git merge upstream/master # you should get a fast-forward message here + git push + +Translations +------------ + +If you want to add your own translation, edit `interface_localization.js` like this: + +1. fork the repo, checkout `i18n` and create a new branch + + + git clone git@github.com:yournickname/twister-html.git ~/.twister/html + cd ~/.twister/html + git checkout i18n + git checkout -b Klingon + +2. add your language to the list of available choices. You should use your ISO code here, +it should match what the browser reports. The Klingon ISO is "tlh", so: + + + var knownLanguages = ["en","nl","it","fr","tlh"];` + +For multi-region languages, if you want to catch them all, use only the first half +(e.g. to match it and it-ch, specify "it"). + +3. add a new wordset block after existing ones + + + if(preferredLanguage == "tlh"){ + polyglot.locale("tlh"); + wordset = { + "Insults": "mu'qaD, + .... + } + } + + +4. commit & push + + + git commit -m "Klingon translation" + git push + +3. When opening the pull request on github, make sure you're pointing to `miguelfreitas:i18n` +as the base, so we can merge it straight away in the right place. For any help, ping @toyg. diff --git a/css/style.css b/css/style.css index 3714b87..a539fab 100644 --- a/css/style.css +++ b/css/style.css @@ -624,7 +624,8 @@ button.disabled:hover font-size: 13px; cursor: pointer; } -.twister-user-name +.twister-user-name, +.twister-by-user-name { font-weight: bold; font-size: 14px; diff --git a/home.html b/home.html index c0480cc..e8adff7 100644 --- a/home.html +++ b/home.html @@ -176,8 +176,10 @@
- Followed by - + Followed by + + +
× @@ -406,7 +408,7 @@
-

All users publicly followed by@

+

All users publicly followed by@

diff --git a/interface_localization.js b/interface_localization.js index 5e1270e..4e916bb 100644 --- a/interface_localization.js +++ b/interface_localization.js @@ -4,7 +4,7 @@ // uses Polyglot.js ( https://github.com/airbnb/polyglot.js ) to translate interface // translators: add your language code here such as "es" for Spanish, "ru" for Russian -var knownLanguages = ["en","nl","it"]; +var knownLanguages = ["en","nl","it", "fr"]; // detect language with JavaScript var preferredLanguage = window.navigator.userLanguage || window.navigator.language || "en"; @@ -386,6 +386,127 @@ if(preferredLanguage == "it"){ } +if(preferredLanguage == "fr"){ + polyglot.locale("fr"); + wordset = { + "Actions ▼": "Actions ▼", + "Active DHT nodes:": "Noeuds DHT actifs: ", + "Add DNS": "Ajouter un DNS", + "Add peer": "Ajouter un pair", + "ajax_error": "Erreur ajax: %{error}", // JavaScript error + "All users publicly followed by": "Tous les utilisateurs suivis publiquement par", + "Available": "Disponible", // username is available + "Block chain information": "Informations à propos de la chaîne de blocs", + "Block chain is up-to-date, twister is ready to use!": "La chaîne de blocs est à jour, Twister est maintenant fonctionnel!", + "Block generation": "Production de blocs", + "Cancel": "Annuler", + "Change user": "Changer d'utilisateur", + "Checking...": "Vérification...", // checking if username is available + "Collapse": "Fermer", // smaller view of a post + "Configure block generation": "Configuration de la production de blocs", + "Connections:": "Connexions: ", // to network + "Connection lost.": "Connexion perdue.", + "days": "%{smart_count} jour |||| %{smart_count} jours", + "Detailed information": "Informations détaillées", + "DHT network down.": "Panne du réseau DHT.", + "Direct Messages": "Messages directs", + "Disable": "Désactiver", + "Display mentions to @": "Afficher les mentions pour @", + "Display retransmissions": "Afficher les retransmissions", + "DNS to obtain list of peers:": "DNS pour obtenir la liste des pairs:", + "downloading_block_chain": "Téléchargement de la chaîne de blocs, s'il vous plaît attendre avant de continuer (la chaîne de blocs a %{days} jours de retard).", + "download_posts_status": "%{portion} billets téléchargés", // Downloaded 10/30 posts + "Enable": "Activer", + "error": "Erreur: %{error}", + "error_connecting_to_daemon": "Erreur de connection, impossible de joindre le démon Twister.", + "Error in 'createwalletuser' RPC.": "Erreur RPC dans 'createwalletuser'.", + "Error in 'importprivkey'": "Erreur RPC dans 'importprivkey': %{rpc}", + "Error in 'sendnewusertransaction' RPC.": "Error RPC dans 'sendnewusertransaction'.", + "Expand": "Ouvrir", // larger view of a post + "Favorite": "Favori", + "File APIs not supported in this browser.": "L'API de fichiers n'est pas pris en charge dans votre navigateur.", + "Follow": "Suivre", + "Followed by": "Suivi par", + "followed_by": "Suivi par %{username}", + "Followers": "Followers", + "Following": "Following", + "Following users": "Following users", + "Force connection to peer:": "Forcer la connection à un pair:", + "General information": "Informations générales", + "Generate blocks (send promoted messages)": "Produire des blocs (envoyer des messages promus)", + "Home": "Début", // homepage + "hours": "%{smart_count} heure |||| %{smart_count} heures", + "Internal error: lastPostId unknown (following yourself may fix!)": "Erreur interne: lastPostId inconnu", + "Known peers:": "Pairs connus: ", + "Last block is ahead of your computer time, check your clock.": "Le dernier bloc est en avance sur le l'heure de votre machine, vérifiez votre horloge.", + "mentions_at": "Mentions @%{user}", + "minutes": "%{smart_count} minute |||| %{smart_count} minutes", + "Must be 16 characters or less.": "Doit contenir de 16 caractères ou moins.", // username + "Network": "Réseau", + "Network config": "Configuration réseau", + "Network status": "Etat du réseau", + "New direct message...": "Nouveau message direct...", + "New Post...": "Nouveau billet...", + "new_posts": "%{smart_count} nouveau billet |||| %{smart_count} nouveaux billets", + "nobody": "nobody", // used to promote a post without attaching the user + "Not available": "Non disponible", // username is not available + "Number of blocks in block chain:": "Nombre de blocs dans la chaîne de blocs: ", + "Number of CPUs to use": "Nombre de processeurs à utiliser", + "Only alphanumeric and underscore allowed.": "Seulement les caractères alphanumérique et la barre de soulignement sont permis.", + "peer address": "adresse des pairs", + "Private": "Privé", + "Profile": "Profil", + "Postboard": "Billets", + "post": "envoyer", // verb - button to post a message + "Post to promote:": "Billet à promouvoir: ", + "Posts": "Posts", + "propagating_nickname": "Multiplication de votre pseudo %{username} sur le réseau...", + "Public": "Public", + "Refresh": "Actualiser", + "retransmit_this": "Retransmettre ce billet à tes followers?", + "Reply": "Répondre", + "Reply...": "Répondre...", + "reply_to": "Répondre à %{fullname}", + "Retransmit": "Retransmission", + "Retransmits": "Retransmissions", + "Retransmitted by": "Retransmis par", + "search": "recherche", + "seconds": "%{smart_count} seconde |||| %{smart_count} secondes", + "send": "envoyer", + "Send post with username": "Envoyer le billet avec le pseudo", + "Sent Direct Message": "Message direct envoyé", + "Sent Post to @": "Envoyé un billet à @", + "Setup account": "Configuration du compte", + "switch_to_network": "Le démon local n'est pas connecté au réseau ou\n" + + "la chaîne de blocs n'est pas à jour. Si vous restez dans cette page\n" + + "vos actions peuvent ne pas fonctionner.\n" + + "Voulez-vous consulter la page d'état du réseau au lieu?", + "The File APIs are not fully supported in this browser.": "L'API de fichier n'est pas entièrement pris en charge dans votre navigateur.", + "time_ago": "Il y a %{time}", // 5 minutes ago + "Time of the last block:": "Heure du dernier bloc: ", + "Type message here": "Tapez votre message ici", + "Unfollow": "Unfollow", + "Update": "Mettre à jour", + "Updating status...": "Mise à jour du statut...", // status of block chain + "user_not_yet_accepted": "Les autres pairs n'ont pas encore accepté ce nouvel utilisateur.\n" + + "Malheureusement, il n'est pas possible d'enregistrer le profil\n" + + "ou envoyer des billets dans cet état.\n\n" + + "S'il vous plaît attendre quelques minutes avant de continuer.\n\n" + + "L'action 'enregistrer' sera automatiquement activé\n" + + "lorsque le processus sera terminé. (Je vous promets que\n"+ + "c'est la dernière fois que vous devrez attendre avant d'utiliser\n" + + "Twister).\n\n" + + "Astuce: choisissez votre avatar entre temps!", + "users_mentions": "Mentions de @%{username}", + "users_profile": "Profil de %{username}", + "username_undefined": "Nom d'utilisateur indéfini, login requis.", + "View": "Voir", + "View All": "Voir tous", + "Who to Follow": "Qui suivre", + "Your message was sent!": "Votre message a été envoyé!" + }; +} + // translators: sample adding a language if(preferredLanguage == "ru"){ // polyglot.locale() is used to support plurals diff --git a/network.html b/network.html index 7723c53..76371a1 100644 --- a/network.html +++ b/network.html @@ -123,7 +123,12 @@ Fri Nov 08 2013 08:32:48 +
  • + + 0.0 +
  • +

    Configure block generation

    @@ -157,6 +162,14 @@ + +

    Block generation status

    + diff --git a/twister_following.js b/twister_following.js index 774862d..e02bf94 100644 --- a/twister_following.js +++ b/twister_following.js @@ -332,6 +332,7 @@ function processSuggestion(arg, suggestion, followedBy) { item.find(".twister-user-info").attr("data-screen-name", suggestion); item.find(".twister-user-name").attr("href", $.MAL.userUrl(suggestion)); + item.find(".twister-by-user-name").attr("href", $.MAL.userUrl(followedBy)); item.find(".twister-user-tag").text("@" + suggestion); getAvatar(suggestion,item.find(".twister-user-photo")); diff --git a/twister_formatpost.js b/twister_formatpost.js index fc98233..8c7f413 100644 --- a/twister_formatpost.js +++ b/twister_formatpost.js @@ -116,7 +116,7 @@ function dmDataToSnippetItem(dmData, remoteUser) { dmItem.find("a.dm-chat-link").attr("href", $.MAL.dmchatUrl(remoteUser)); getAvatar( remoteUser, dmItem.find(".post-photo").find("img") ); getFullname( remoteUser, dmItem.find("a.post-info-name") ); - dmItem.find(".post-text").text(escapeHtmlEntities(dmData.text)); + dmItem.find(".post-text").html(escapeHtmlEntities(dmData.text)); dmItem.find(".post-info-time").text(timeGmtToText(dmData.time)); dmItem.find(".post-info-time").attr("title",timeSincePost(dmData.time)); diff --git a/twister_network.js b/twister_network.js index 67ecb1b..b917ce6 100644 --- a/twister_network.js +++ b/twister_network.js @@ -140,6 +140,32 @@ function networkUpdate(cbFunc, cbArg) { }); } +function getMiningInfo(cbFunc, cbArg) { + twisterRpc("getmininginfo", [], + function(args, ret) { + miningDifficulty = ret.difficulty; + miningHashRate = ret.hashespersec; + + $(".mining-difficulty").text(miningDifficulty); + $(".mining-hashrate").text(miningHashRate); +/* + if( !twisterdConnections ) { + $.MAL.setNetworkStatusMsg("Connection lost.", false); + twisterdConnectedAndUptodate = false; + } +*/ + if( args.cbFunc ) + args.cbFunc(args.cbArg); + }, {cbFunc:cbFunc, cbArg:cbArg}, + function(args, ret) { + console.log("Error connecting to local twister daemon."); + }, {}); +} + +function miningUpdate(cbFunc, cbArg) { + getMiningInfo(cbFunc, cbArg); +} + function getGenerate() { twisterRpc("getgenerate", [], function(args, ret) { @@ -219,6 +245,10 @@ function initInterfaceNetwork() { }); networkUpdate(); setInterval("networkUpdate()", 2000); + + miningUpdate(); + setInterval("miningUpdate()", 2000); + getGenerate(); interfaceNetworkHandlers();