1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Added command to export debug information from mobile and CLI

This commit is contained in:
Laurent Cozic 2017-11-21 18:48:50 +00:00
parent c5214b6c44
commit 3722012da5
23 changed files with 408 additions and 130 deletions

View File

@ -91,6 +91,10 @@ const headerHtml = `<!doctype html>
.cli-screenshot .prompt {
color: #48C2F0;
}
.top-screenshot {
margin-top: 2em;
text-align: center;
}
.header {
position: relative;
padding-left: 2em;
@ -150,15 +154,29 @@ const headerHtml = `<!doctype html>
width: 100%;
text-align: right;
vertical-align: middle;
padding-top: 3px;
line-height: 0;
}
.twitter-share-button {
.nav-right .share-btn {
display: none;
}
.github-share-button {
.share-btn-github {
display: inline-block;
}
</style>
.nav-right .small-share-btn {
display: none;
}
.nav-right .share-btn-github {
display: inline-block;
}
@media all and (min-width: 400px) {
.nav-right .share-btn {
display: inline-block;
}
.nav-right .small-share-btn {
display: none;
}
}
</style>
</head>
<body>
@ -179,9 +197,9 @@ const headerHtml = `<!doctype html>
<li class="{{selectedDesktop}}"><a href="{{baseUrl}}/desktop" title="Desktop"><i class="fa fa-desktop"></i></a></li>
</ul>
<div class="nav-right">
<iframe src="https://www.facebook.com/plugins/share_button.php?href=http%3A%2F%2Fjoplin.cozic.net&layout=button&size=small&mobile_iframe=true&width=60&height=20&appId" width="60" height="20" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowTransparency="true"></iframe>
<a class="twitter-share-button" href="https://twitter.com/intent/tweet?url=http%3A%2F%2Fjoplin.cozic.net">Tweet</a>
<iframe class="github-share-button" src="https://ghbtns.com/github-btn.html?user=laurent22&repo=joplin&type=star&count=true" frameborder="0" scrolling="0" width="80px" height="20px"></iframe>
<iframe class="share-btn" src="https://www.facebook.com/plugins/share_button.php?href=http%3A%2F%2Fjoplin.cozic.net&layout=button&size=small&mobile_iframe=true&width=60&height=20&appId" width="60" height="20" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowTransparency="true"></iframe>
<iframe class="share-btn" src="https://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fjoplin.cozic.net" width="62" height="20" title="Tweet" style="border: 0; overflow: hidden;"></iframe>
<iframe class="share-btn share-btn-github" src="https://ghbtns.com/github-btn.html?user=laurent22&repo=joplin&type=star&count=true" frameborder="0" scrolling="0" width="80px" height="20px"></iframe>
</div>
</div>
</div>
@ -230,21 +248,6 @@ const footerHtml = `
// `;
const scriptHtml = `
<script>window.twttr = (function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0],
t = window.twttr || {};
if (d.getElementById(id)) return t;
js = d.createElement(s);
js.id = id;
js.src = "https://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
t._e = [];
t.ready = function(f) {
t._e.push(f);
};
return t;
}(document, "script", "twitter-wjs"));</script>
<script>
function stickyHeader() {
if ($(window).scrollTop() > 179) {
@ -267,6 +270,10 @@ const scriptHtml = `
</script>
`;
// <a href="#" class="small-share-btn" style="background-color: #365899;"><img src="images/ShareFacebook.svg" style=" width: 1.2em; height: 1.2em"/></a>
// <a href="#" class="small-share-btn" style="background-color: #1b95e0;"><img src="images/ShareTwitter.svg" style=" width: 1.2em; height: 1.2em"/></a>
// <a href="#" class="small-share-btn" style="background-color: #eee;"><img src="images/ShareGithub.svg" style=" width: 1.2em; height: 1.2em"/></a>
const rootDir = dirname(dirname(__dirname));
function markdownToHtml(md) {

View File

@ -0,0 +1,36 @@
const { BaseCommand } = require('./base-command.js');
const { Database } = require('lib/database.js');
const { app } = require('./app.js');
const { Setting } = require('lib/models/setting.js');
const { _ } = require('lib/locale.js');
const { ReportService } = require('lib/services/report.js');
const fs = require('fs-extra');
class Command extends BaseCommand {
usage() {
return 'export-sync-status';
}
description() {
return 'Export sync status';
}
hidden() {
return true;
}
async action(args) {
const service = new ReportService();
const csv = await service.basicItemList({ format: 'csv' });
const filePath = Setting.value('profileDir') + '/syncReport-' + (new Date()).getTime() + '.csv';
await fs.writeFileSync(filePath, csv);
this.stdout('Sync status exported to ' + filePath);
app().gui().showConsole();
app().gui().maximizeConsole();
}
}
module.exports = Command;

View File

@ -822,6 +822,9 @@ msgstr ""
msgid "Status"
msgstr ""
msgid "Export Status Data"
msgstr ""
msgid "Cancel synchronisation"
msgstr ""

View File

@ -887,6 +887,9 @@ msgstr "Journal"
msgid "Status"
msgstr "État"
msgid "Export Status Data"
msgstr ""
msgid "Cancel synchronisation"
msgstr "Annuler synchronisation"

View File

@ -822,6 +822,9 @@ msgstr ""
msgid "Status"
msgstr ""
msgid "Export Status Data"
msgstr ""
msgid "Cancel synchronisation"
msgstr ""

View File

@ -1,6 +1,6 @@
{
"name": "joplin",
"version": "0.10.71",
"version": "0.10.72",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -18,7 +18,7 @@
],
"owner": "Laurent Cozic"
},
"version": "0.10.71",
"version": "0.10.72",
"bin": {
"joplin": "./main.js"
},

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8,7 +8,7 @@ The notes can be [synchronised](#synchronisation) with various targets including
Joplin is still under development but is out of Beta and should be suitable for every day use. The UI of the terminal client is built on top of the great [terminal-kit](https://github.com/cronvel/terminal-kit) library, the desktop client using [Electron](https://electronjs.org/), and the Android client front end is done using [React Native](https://facebook.github.io/react-native/).
<img src="https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/AllClients.jpg" style="max-width: 100%">
<div class="top-screenshot"><img src="https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/AllClients.jpg" style="max-width: 100%; max-height: 35em;"></div>
# Installation
@ -16,18 +16,18 @@ Three types of applications are available: **desktop** (Windows, macOS and Linux
## Desktop applications
Operating system | Link
Operating System | Download
-----------------|--------
Windows | <a href='https://github.com/laurent22/joplin/releases/download/v0.10.22/Joplin-Setup-0.10.22.exe'><img alt='Get it on Windows' height="60px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeWindows.png'/></a>
macOS | <a href='https://github.com/laurent22/joplin/releases/download/v0.10.22/Joplin-0.10.22.dmg'><img alt='Get it on macOS' height="60px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeMacOS.png'/></a>
Linux | <a href='https://github.com/laurent22/joplin/releases/download/v0.10.22/Joplin-0.10.22-x86_64.AppImage'><img alt='Get it on macOS' height="60px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeLinux.png'/></a>
Windows | <a href='https://github.com/laurent22/joplin/releases/download/v0.10.22/Joplin-Setup-0.10.22.exe'><img alt='Get it on Windows' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeWindows.png'/></a>
macOS | <a href='https://github.com/laurent22/joplin/releases/download/v0.10.22/Joplin-0.10.22.dmg'><img alt='Get it on macOS' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeMacOS.png'/></a>
Linux | <a href='https://github.com/laurent22/joplin/releases/download/v0.10.22/Joplin-0.10.22-x86_64.AppImage'><img alt='Get it on macOS' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeLinux.png'/></a>
## Mobile applications
Operating system | Link
Operating System | Download
-----------------|--------
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="60px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeAndroid.png'/></a>
iOS | <a href='#'><img alt='Get it on the App Store' height="60px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeIOS.png'/></a>
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeAndroid.png'/></a>
iOS | <a href='#'><img alt='Get it on the App Store' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeIOS.png'/></a>
## Terminal application
@ -108,15 +108,16 @@ This translation will apply to both the terminal and the Android application.
# Coming features
The two main features that remain to be implemented are:
- iOS application (80% done)
- End to end encryption (to-do)
- All: End to end encryption
- Windows: Tray icon
- Desktop apps: Tag auto-complete
- Desktop apps: Dark theme
- Linux: Enable auto-update for desktop app
# Known bugs
- Non-alphabetical characters such as Chinese or Arabic might create glitches in the terminal on Windows. This is a limitation of the current Windows console.
- In the React Native app, changing the notebook of a note sometimes has no effect, due to [this bug](https://github.com/facebook/react-native/issues/15556). Due to [this other bug](https://github.com/facebook/react-native/issues/13351), changing one config value sometimes also set a different one. This is likely to be resolved soon in a future version of React Native.
- Auto-update is not working in the Linux desktop application.
# License

View File

@ -90,8 +90,8 @@ android {
applicationId "net.cozic.joplin"
minSdkVersion 16
targetSdkVersion 22
versionCode 64
versionName "0.10.51"
versionCode 66
versionName "0.10.53"
ndk {
abiFilters "armeabi-v7a", "x86"
}

View File

@ -4,6 +4,7 @@ const { Platform, View, Text, Button, StyleSheet, TouchableOpacity, Image } = re
const Icon = require('react-native-vector-icons/Ionicons').default;
const { Log } = require('lib/log.js');
const { BackButtonService } = require('lib/services/back-button.js');
const { ReportService } = require('lib/services/report.js');
const { Menu, MenuOptions, MenuOption, MenuTrigger } = require('react-native-popup-menu');
const { _ } = require('lib/locale.js');
const { Setting } = require('lib/models/setting.js');
@ -13,6 +14,8 @@ const { reg } = require('lib/registry.js');
const { themeStyle } = require('lib/components/global-style.js');
const { ItemList } = require('lib/components/ItemList.js');
const { Dropdown } = require('lib/components/Dropdown.js');
const { time } = require('lib/time-utils');
const RNFS = require('react-native-fs');
// Rather than applying a padding to the whole bar, it is applied to each
// individual component (button, picker, etc.) so that the touchable areas
@ -181,6 +184,32 @@ class ScreenHeaderComponent extends Component {
});
}
async debugReport_press() {
const service = new ReportService();
const logItems = await reg.logger().lastEntries(null);
const logItemRows = [
['Date','Level','Message']
];
for (let i = 0; i < logItems.length; i++) {
const item = logItems[i];
logItemRows.push([
time.formatMsToLocal(item.timestamp, 'MM-DDTHH:mm:ss'),
item.level,
item.message
]);
}
const logItemCsv = service.csvCreate(logItemRows);
const itemListCsv = await service.basicItemList({ format: 'csv' });
const filePath = RNFS.ExternalDirectoryPath + '/syncReport-' + (new Date()).getTime() + '.txt';
const finalText = [logItemCsv, itemListCsv].join("\n--------------------------------------------------------------------------------");
await RNFS.writeFile(filePath, finalText);
alert('Debug report exported to ' + filePath);
}
render() {
function sideMenuButton(styles, onPress) {
@ -243,14 +272,21 @@ class ScreenHeaderComponent extends Component {
}
menuOptionComponents.push(
<MenuOption value={() => this.log_press()} key={'menuOption_' + key++} style={this.styles().contextMenuItem}>
<MenuOption value={() => this.log_press()} key={'menuOption_log'} style={this.styles().contextMenuItem}>
<Text style={this.styles().contextMenuItemText}>{_('Log')}</Text>
</MenuOption>);
menuOptionComponents.push(
<MenuOption value={() => this.status_press()} key={'menuOption_' + key++} style={this.styles().contextMenuItem}>
<MenuOption value={() => this.status_press()} key={'menuOption_status'} style={this.styles().contextMenuItem}>
<Text style={this.styles().contextMenuItemText}>{_('Status')}</Text>
</MenuOption>);
if (Platform.OS === 'android') {
menuOptionComponents.push(
<MenuOption value={() => this.debugReport_press()} key={'menuOption_debugReport'} style={this.styles().contextMenuItem}>
<Text style={this.styles().contextMenuItemText}>{_('Export Debug Report')}</Text>
</MenuOption>);
}
}
if (menuOptionComponents.length) {

View File

@ -85,7 +85,9 @@ class Logger {
for (let i = 0; i < this.targets_.length; i++) {
const target = this.targets_[i];
if (target.type == 'database') {
return await target.database.selectAll('SELECT * FROM logs ORDER BY timestamp DESC LIMIT ' + limit);
let sql = 'SELECT * FROM logs ORDER BY timestamp DESC';
if (limit !== null) sql += ' LIMIT ' + limit
return await target.database.selectAll(sql);
}
}
return [];

View File

@ -404,6 +404,9 @@ class BaseItem extends BaseModel {
return this.db().transactionExecBatch(queries);
}
// When an item is deleted, its associated sync_items data is not immediately deleted for
// performance reason. So this function is used to look for these remaining sync_items and
// delete them.
static async deleteOrphanSyncItems() {
const classNames = this.syncItemClassNames();

View File

@ -6,6 +6,65 @@ const { _ } = require('lib/locale.js');
class ReportService {
csvEscapeCell(cell) {
cell = this.csvValueToString(cell);
let output = cell.replace(/"/, '""');
if (this.csvCellRequiresQuotes(cell, ',')) {
return '"' + output + '"';
}
return output;
}
csvCellRequiresQuotes(cell, delimiter) {
if (cell.indexOf('\n') >= 0) return true;
if (cell.indexOf('"') >= 0) return true;
if (cell.indexOf(delimiter) >= 0) return true;
return false;
}
csvValueToString(v) {
if (v === undefined || v === null) return '';
return v.toString();
}
csvCreateLine(row) {
for (let i = 0; i < row.length; i++) {
row[i] = this.csvEscapeCell(row[i]);
}
return row.join(',');
}
csvCreate(rows) {
let output = [];
for (let i = 0; i < rows.length; i++) {
output.push(this.csvCreateLine(rows[i]));
}
return output.join('\n');
}
async basicItemList(option = null) {
if (!option) option = {};
if (!option.format) option.format = 'array';
const itemTypes = BaseItem.syncItemTypes();
let output = [];
output.push(['type', 'id', 'updated_time', 'sync_time', 'is_conflict']);
for (let i = 0; i < itemTypes.length; i++) {
const itemType = itemTypes[i];
const ItemClass = BaseItem.getClassByItemType(itemType);
const items = await ItemClass.modelSelectAll('SELECT items.id, items.updated_time, sync_items.sync_time FROM ' + ItemClass.tableName() + ' items JOIN sync_items ON sync_items.item_id = items.id');
for (let j = 0; j < items.length; j++) {
const item = items[j];
let row = [itemType, item.id, item.updated_time, item.sync_time];
row.push(('is_conflict' in item) ? item.is_conflict : '');
output.push(row);
}
}
return option.format === 'csv' ? this.csvCreate(output) : output;
}
async syncStatus(syncTarget) {
let output = {
items: {},

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -85,6 +85,10 @@
.cli-screenshot .prompt {
color: #48C2F0;
}
.top-screenshot {
margin-top: 2em;
text-align: center;
}
.header {
position: relative;
padding-left: 2em;
@ -144,15 +148,29 @@
width: 100%;
text-align: right;
vertical-align: middle;
padding-top: 3px;
line-height: 0;
}
.twitter-share-button {
.nav-right .share-btn {
display: none;
}
.github-share-button {
.share-btn-github {
display: inline-block;
}
</style>
.nav-right .small-share-btn {
display: none;
}
.nav-right .share-btn-github {
display: inline-block;
}
@media all and (min-width: 400px) {
.nav-right .share-btn {
display: inline-block;
}
.nav-right .small-share-btn {
display: none;
}
}
</style>
</head>
<body>
@ -173,9 +191,9 @@
<li class="selected"><a href="http:&#x2F;&#x2F;joplin.cozic.net/desktop" title="Desktop"><i class="fa fa-desktop"></i></a></li>
</ul>
<div class="nav-right">
<iframe src="https://www.facebook.com/plugins/share_button.php?href=http%3A%2F%2Fjoplin.cozic.net&layout=button&size=small&mobile_iframe=true&width=60&height=20&appId" width="60" height="20" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowTransparency="true"></iframe>
<a class="twitter-share-button" href="https://twitter.com/intent/tweet?url=http%3A%2F%2Fjoplin.cozic.net">Tweet</a>
<iframe class="github-share-button" src="https://ghbtns.com/github-btn.html?user=laurent22&repo=joplin&type=star&count=true" frameborder="0" scrolling="0" width="80px" height="20px"></iframe>
<iframe class="share-btn" src="https://www.facebook.com/plugins/share_button.php?href=http%3A%2F%2Fjoplin.cozic.net&layout=button&size=small&mobile_iframe=true&width=60&height=20&appId" width="60" height="20" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowTransparency="true"></iframe>
<iframe class="share-btn" src="https://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fjoplin.cozic.net" width="62" height="20" title="Tweet" style="border: 0; overflow: hidden;"></iframe>
<iframe class="share-btn share-btn-github" src="https://ghbtns.com/github-btn.html?user=laurent22&repo=joplin&type=star&count=true" frameborder="0" scrolling="0" width="80px" height="20px"></iframe>
</div>
</div>
</div>
@ -183,21 +201,6 @@
<div class="content">
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/DemoDesktop.png" style="max-width: 100%"></p>
<script>window.twttr = (function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0],
t = window.twttr || {};
if (d.getElementById(id)) return t;
js = d.createElement(s);
js.id = id;
js.src = "https://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
t._e = [];
t.ready = function(f) {
t._e.push(f);
};
return t;
}(document, "script", "twitter-wjs"));</script>
<script>
function stickyHeader() {
if ($(window).scrollTop() > 179) {

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
aria-labelledby="simpleicons-facebook-icon"
role="img"
viewBox="0 0 24 24"
version="1.1"
id="svg5"
sodipodi:docname="ShareFacebook.svg"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
<metadata
id="metadata11">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs9" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1017"
id="namedview7"
showgrid="false"
inkscape:zoom="9.8333333"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg5" />
<title
id="simpleicons-facebook-icon">Facebook icon</title>
<path
d="M22.676 0H1.324C.593 0 0 .593 0 1.324v21.352C0 23.408.593 24 1.324 24h11.494v-9.294H9.689v-3.621h3.129V8.41c0-3.099 1.894-4.785 4.659-4.785 1.325 0 2.464.097 2.796.141v3.24h-1.921c-1.5 0-1.792.721-1.792 1.771v2.311h3.584l-.465 3.63H16.56V24h6.115c.733 0 1.325-.592 1.325-1.324V1.324C24 .593 23.408 0 22.676 0"
id="path3"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1 @@
<svg aria-labelledby="simpleicons-github-icon" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title id="simpleicons-github-icon">GitHub icon</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>

After

Width:  |  Height:  |  Size: 898 B

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
aria-labelledby="simpleicons-twitter-icon"
role="img"
viewBox="0 0 24 24"
version="1.1"
id="svg5"
sodipodi:docname="ShareTwitter.svg"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)">
<metadata
id="metadata11">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs9" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1017"
id="namedview7"
showgrid="false"
inkscape:zoom="9.8333333"
inkscape:cx="12"
inkscape:cy="12"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg5" />
<title
id="simpleicons-twitter-icon">Twitter icon</title>
<path
d="M23.954 4.569c-.885.389-1.83.654-2.825.775 1.014-.611 1.794-1.574 2.163-2.723-.951.555-2.005.959-3.127 1.184-.896-.959-2.173-1.559-3.591-1.559-2.717 0-4.92 2.203-4.92 4.917 0 .39.045.765.127 1.124C7.691 8.094 4.066 6.13 1.64 3.161c-.427.722-.666 1.561-.666 2.475 0 1.71.87 3.213 2.188 4.096-.807-.026-1.566-.248-2.228-.616v.061c0 2.385 1.693 4.374 3.946 4.827-.413.111-.849.171-1.296.171-.314 0-.615-.03-.916-.086.631 1.953 2.445 3.377 4.604 3.417-1.68 1.319-3.809 2.105-6.102 2.105-.39 0-.779-.023-1.17-.067 2.189 1.394 4.768 2.209 7.557 2.209 9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63.961-.689 1.8-1.56 2.46-2.548l-.047-.02z"
id="path3"
style="fill:#ffffff" />
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -85,6 +85,10 @@
.cli-screenshot .prompt {
color: #48C2F0;
}
.top-screenshot {
margin-top: 2em;
text-align: center;
}
.header {
position: relative;
padding-left: 2em;
@ -144,15 +148,29 @@
width: 100%;
text-align: right;
vertical-align: middle;
padding-top: 3px;
line-height: 0;
}
.twitter-share-button {
.nav-right .share-btn {
display: none;
}
.github-share-button {
.share-btn-github {
display: inline-block;
}
</style>
.nav-right .small-share-btn {
display: none;
}
.nav-right .share-btn-github {
display: inline-block;
}
@media all and (min-width: 400px) {
.nav-right .share-btn {
display: inline-block;
}
.nav-right .small-share-btn {
display: none;
}
}
</style>
</head>
<body>
@ -173,9 +191,9 @@
<li class=""><a href="http:&#x2F;&#x2F;joplin.cozic.net/desktop" title="Desktop"><i class="fa fa-desktop"></i></a></li>
</ul>
<div class="nav-right">
<iframe src="https://www.facebook.com/plugins/share_button.php?href=http%3A%2F%2Fjoplin.cozic.net&layout=button&size=small&mobile_iframe=true&width=60&height=20&appId" width="60" height="20" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowTransparency="true"></iframe>
<a class="twitter-share-button" href="https://twitter.com/intent/tweet?url=http%3A%2F%2Fjoplin.cozic.net">Tweet</a>
<iframe class="github-share-button" src="https://ghbtns.com/github-btn.html?user=laurent22&repo=joplin&type=star&count=true" frameborder="0" scrolling="0" width="80px" height="20px"></iframe>
<iframe class="share-btn" src="https://www.facebook.com/plugins/share_button.php?href=http%3A%2F%2Fjoplin.cozic.net&layout=button&size=small&mobile_iframe=true&width=60&height=20&appId" width="60" height="20" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowTransparency="true"></iframe>
<iframe class="share-btn" src="https://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fjoplin.cozic.net" width="62" height="20" title="Tweet" style="border: 0; overflow: hidden;"></iframe>
<iframe class="share-btn share-btn-github" src="https://ghbtns.com/github-btn.html?user=laurent22&repo=joplin&type=star&count=true" frameborder="0" scrolling="0" width="80px" height="20px"></iframe>
</div>
</div>
</div>
@ -185,29 +203,30 @@
<p>Notes exported from Evernote via .enex files <a href="#importing-notes-from-evernote">can be imported</a> into Joplin, including the formatted content (which is converted to markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.).</p>
<p>The notes can be <a href="#synchronisation">synchronised</a> with various targets including the file system (for example with a network directory) or with Microsoft OneDrive. When synchronising the notes, notebooks, tags and other metadata are saved to plain text files which can be easily inspected, backed up and moved around.</p>
<p>Joplin is still under development but is out of Beta and should be suitable for every day use. The UI of the terminal client is built on top of the great <a href="https://github.com/cronvel/terminal-kit">terminal-kit</a> library, the desktop client using <a href="https://electronjs.org/">Electron</a>, and the Android client front end is done using <a href="https://facebook.github.io/react-native/">React Native</a>.</p>
<p><img src="https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/AllClients.jpg" style="max-width: 100%"></p>
<div class="top-screenshot"><img src="https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/AllClients.jpg" style="max-width: 100%; max-height: 35em;"></div>
<h1 id="installation">Installation</h1>
<p>Three types of applications are available: <strong>desktop</strong> (Windows, macOS and Linux), <strong>mobile</strong> (Android and iOS) and for <strong>terminal</strong> (Windows, macOS and Linux). All applications have similar user interfaces and can synchronise with each others.</p>
<h2 id="desktop-applications">Desktop applications</h2>
<table>
<thead>
<tr>
<th>Operating system</th>
<th>Link</th>
<th>Operating System</th>
<th>Download</th>
</tr>
</thead>
<tbody>
<tr>
<td>Windows</td>
<td><a href='https://github.com/laurent22/joplin/releases/download/v0.10.22/Joplin-Setup-0.10.22.exe'><img alt='Get it on Windows' height="60px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeWindows.png'/></a></td>
<td><a href='https://github.com/laurent22/joplin/releases/download/v0.10.22/Joplin-Setup-0.10.22.exe'><img alt='Get it on Windows' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeWindows.png'/></a></td>
</tr>
<tr>
<td>macOS</td>
<td><a href='https://github.com/laurent22/joplin/releases/download/v0.10.22/Joplin-0.10.22.dmg'><img alt='Get it on macOS' height="60px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeMacOS.png'/></a></td>
<td><a href='https://github.com/laurent22/joplin/releases/download/v0.10.22/Joplin-0.10.22.dmg'><img alt='Get it on macOS' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeMacOS.png'/></a></td>
</tr>
<tr>
<td>Linux</td>
<td><a href='https://github.com/laurent22/joplin/releases/download/v0.10.22/Joplin-0.10.22-x86_64.AppImage'><img alt='Get it on macOS' height="60px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeLinux.png'/></a></td>
<td><a href='https://github.com/laurent22/joplin/releases/download/v0.10.22/Joplin-0.10.22-x86_64.AppImage'><img alt='Get it on macOS' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeLinux.png'/></a></td>
</tr>
</tbody>
</table>
@ -215,18 +234,18 @@
<table>
<thead>
<tr>
<th>Operating system</th>
<th>Link</th>
<th>Operating System</th>
<th>Download</th>
</tr>
</thead>
<tbody>
<tr>
<td>Android</td>
<td><a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="60px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeAndroid.png'/></a></td>
<td><a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeAndroid.png'/></a></td>
</tr>
<tr>
<td>iOS</td>
<td><a href='#'><img alt='Get it on the App Store' height="60px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeIOS.png'/></a></td>
<td><a href='#'><img alt='Get it on the App Store' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeIOS.png'/></a></td>
</tr>
</tbody>
</table>
@ -289,15 +308,17 @@
</ul>
<p>This translation will apply to both the terminal and the Android application.</p>
<h1 id="coming-features">Coming features</h1>
<p>The two main features that remain to be implemented are:</p>
<ul>
<li>iOS application (80% done)</li>
<li>End to end encryption (to-do)</li>
<li>All: End to end encryption</li>
<li>Windows: Tray icon</li>
<li>Desktop apps: Tag auto-complete</li>
<li>Desktop apps: Dark theme</li>
<li>Linux: Enable auto-update for desktop app</li>
</ul>
<h1 id="known-bugs">Known bugs</h1>
<ul>
<li>Non-alphabetical characters such as Chinese or Arabic might create glitches in the terminal on Windows. This is a limitation of the current Windows console.</li>
<li>In the React Native app, changing the notebook of a note sometimes has no effect, due to <a href="https://github.com/facebook/react-native/issues/15556">this bug</a>. Due to <a href="https://github.com/facebook/react-native/issues/13351">this other bug</a>, changing one config value sometimes also set a different one. This is likely to be resolved soon in a future version of React Native.</li>
<li>Auto-update is not working in the Linux desktop application.</li>
</ul>
<h1 id="license">License</h1>
<p>Copyright (c) 2016-2017 Laurent Cozic</p>
@ -305,21 +326,6 @@
<p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</p>
<p>THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p>
<script>window.twttr = (function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0],
t = window.twttr || {};
if (d.getElementById(id)) return t;
js = d.createElement(s);
js.id = id;
js.src = "https://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
t._e = [];
t.ready = function(f) {
t._e.push(f);
};
return t;
}(document, "script", "twitter-wjs"));</script>
<script>
function stickyHeader() {
if ($(window).scrollTop() > 179) {

View File

@ -85,6 +85,10 @@
.cli-screenshot .prompt {
color: #48C2F0;
}
.top-screenshot {
margin-top: 2em;
text-align: center;
}
.header {
position: relative;
padding-left: 2em;
@ -144,15 +148,29 @@
width: 100%;
text-align: right;
vertical-align: middle;
padding-top: 3px;
line-height: 0;
}
.twitter-share-button {
.nav-right .share-btn {
display: none;
}
.github-share-button {
.share-btn-github {
display: inline-block;
}
</style>
.nav-right .small-share-btn {
display: none;
}
.nav-right .share-btn-github {
display: inline-block;
}
@media all and (min-width: 400px) {
.nav-right .share-btn {
display: inline-block;
}
.nav-right .small-share-btn {
display: none;
}
}
</style>
</head>
<body>
@ -173,9 +191,9 @@
<li class=""><a href="http:&#x2F;&#x2F;joplin.cozic.net/desktop" title="Desktop"><i class="fa fa-desktop"></i></a></li>
</ul>
<div class="nav-right">
<iframe src="https://www.facebook.com/plugins/share_button.php?href=http%3A%2F%2Fjoplin.cozic.net&layout=button&size=small&mobile_iframe=true&width=60&height=20&appId" width="60" height="20" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowTransparency="true"></iframe>
<a class="twitter-share-button" href="https://twitter.com/intent/tweet?url=http%3A%2F%2Fjoplin.cozic.net">Tweet</a>
<iframe class="github-share-button" src="https://ghbtns.com/github-btn.html?user=laurent22&repo=joplin&type=star&count=true" frameborder="0" scrolling="0" width="80px" height="20px"></iframe>
<iframe class="share-btn" src="https://www.facebook.com/plugins/share_button.php?href=http%3A%2F%2Fjoplin.cozic.net&layout=button&size=small&mobile_iframe=true&width=60&height=20&appId" width="60" height="20" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowTransparency="true"></iframe>
<iframe class="share-btn" src="https://platform.twitter.com/widgets/tweet_button.html?url=http%3A%2F%2Fjoplin.cozic.net" width="62" height="20" title="Tweet" style="border: 0; overflow: hidden;"></iframe>
<iframe class="share-btn share-btn-github" src="https://ghbtns.com/github-btn.html?user=laurent22&repo=joplin&type=star&count=true" frameborder="0" scrolling="0" width="80px" height="20px"></iframe>
</div>
</div>
</div>
@ -474,21 +492,6 @@ version
<p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</p>
<p>THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p>
<script>window.twttr = (function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0],
t = window.twttr || {};
if (d.getElementById(id)) return t;
js = d.createElement(s);
js.id = id;
js.src = "https://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js, fjs);
t._e = [];
t.ready = function(f) {
t._e.push(f);
};
return t;
}(document, "script", "twitter-wjs"));</script>
<script>
function stickyHeader() {
if ($(window).scrollTop() > 179) {