New feature: add article

pull/1/head
Grégory Oestreicher 2016-12-20 14:14:37 +01:00
parent 7cb5186e49
commit d16729bc82
5 changed files with 248 additions and 14 deletions

View File

@ -526,6 +526,60 @@ function deleteArticle( server, id )
); );
} }
function uploadNewArticle( props, articleUrl, cb )
{
var url = props.url;
if ( url.charAt( url.length - 1 ) !== "/" )
url += "/";
url += "api/entries.json";
var params = "url=" + escape( articleUrl );
var http = new XMLHttpRequest;
http.onreadystatechange = function() {
if ( http.readyState === XMLHttpRequest.DONE ) {
var json = null;
var err = null;
if ( http.status === 200 ) {
try {
json = JSON.parse( http.responseText );
}
catch( e ) {
json = null;
err = "failed to parse server response";
}
if ( err !== null )
cb( json, err );
else
_embedImages(
json,
function( content ) {
json.content = content;
cb( json, null );
}
)
}
else {
err = "server returned '" + http.statusText + "'";
}
cb( json, err );
}
};
http.open( "POST", url, true );
http.setRequestHeader( "Content-type", "application/x-www-form-urlencoded" );
http.setRequestHeader( "Content-length", params.length );
http.setRequestHeader( "Authorization:", "Bearer " + props.token );
http.setRequestHeader( "Accept", "application/json" );
http.setRequestHeader( "Connection", "close" );
http.send( params );
}
function downloadArticles( props, cb ) function downloadArticles( props, cb )
{ {
var url = props.url; var url = props.url;

View File

@ -87,7 +87,99 @@ Page {
} }
} }
MouseArea {
id: addArticleContainer
width: parent.width
height: listView.height
x: 0
y: listView.height
z: 5
ParallelAnimation {
id: showAddArticleContainer
PropertyAnimation {
target: addArticleContainer
property: "y"
to: 0
duration: 150
easing.type: Easing.InOutQuad
}
}
ParallelAnimation {
id: hideAddArticleContainer
PropertyAnimation {
target: addArticleContainer
property: "y"
to: listView.height
duration: 150
easing.type: Easing.InOutQuad
}
}
Rectangle {
height: addArticleUrl.height + addArticleUrl.anchors.topMargin + addArticlesButtonRow.height
width: parent.width
anchors.bottom: parent.bottom
anchors.left: parent.left
color: "black"
opacity: 0.9
}
Item {
height: addArticleUrl.height + addArticleUrl.anchors.topMargin + addArticlesButtonRow.height
width: parent.width
anchors.bottom: parent.bottom
anchors.left: parent.left
TextField {
id: addArticleUrl
width: parent.width
anchors.top: parent.top
anchors.topMargin: Theme.horizontalPageMargin
placeholderText: qsTr( "Article URL" )
inputMethodHints: Qt.ImhNoPredictiveText | Qt.ImhUrlCharactersOnly
}
Row {
id: addArticlesButtonRow
anchors.top: addArticleUrl.bottom
spacing: 2 * Theme.paddingLarge
width: addArticleCancel.width + addArticleConfirm.width + Theme.paddingLarge
x: ( parent.width / 2 ) - ( ( 2 * spacing + addArticleCancel.width + addArticleConfirm.width ) / 2 )
IconButton {
id: addArticleCancel
icon.source: "image://theme/icon-m-dismiss"
onClicked: {
addArticleUrl.text = ""
hideAddArticleContainer.start()
}
}
IconButton {
id: addArticleConfirm
icon.source: "image://theme/icon-m-acknowledge"
onClicked: {
serverPage.server.uploadArticle(
addArticleUrl.text,
function() {
addArticleUrl.text = ""
hideAddArticleContainer.start()
}
)
}
}
}
}
}
SilicaListView { SilicaListView {
id: listView
anchors.fill: parent anchors.fill: parent
spacing: Theme.paddingMedium spacing: Theme.paddingMedium
model: articlesModel model: articlesModel
@ -120,6 +212,14 @@ Page {
) )
} }
} }
MenuItem {
text: qsTr( "Add article" )
onClicked: {
showAddArticleContainer.start()
addArticleUrl.focus = true
}
}
} }
header: PageHeader { header: PageHeader {

View File

@ -169,6 +169,48 @@ Item {
articlesDownloaded( ret ) articlesDownloaded( ret )
} }
function uploadArticle( articleUrl, cb ) {
connect(
function( err ) {
if ( err !== null ) {
error( qsTr( "Failed to connect to server: " ) + err)
}
else {
console.debug( "Sending a new article" )
var props = { url: url, token: accessToken }
WallaBase.uploadNewArticle( props, articleUrl, function( content, err ) { onUploadArticleDone( content, err ); cb(); } )
}
}
)
}
function onUploadArticleDone( current, err ) {
if ( err !== null ) {
error( qsTr( "Failed to upload article: " ) + err )
}
else {
var article = {
id: current.id,
server: serverId,
created: current.created_at,
updated: current.updated_at,
mimetype: current.mimetype,
language: current.language,
readingTime: current.reading_time,
url: current.url,
domain: current.domain_name,
archived: current.is_archived,
starred: current.is_starred,
title: current.title,
previewPicture: current.previewPicture,
content: current.content
}
WallaBase.saveArticle( article )
}
articlesDownloaded( [] )
}
function toggleArticleStar( article, cb ) { function toggleArticleStar( article, cb ) {
connect( connect(
function( err ) { function( err ) {

View File

@ -8,6 +8,13 @@
<translation>WallaRead</translation> <translation>WallaRead</translation>
</message> </message>
</context> </context>
<context>
<name>ImageEmbedRequest</name>
<message>
<source>Failed to find the image source</source>
<translation type="unfinished"></translation>
</message>
</context>
<context> <context>
<name>Server</name> <name>Server</name>
<message> <message>
@ -24,15 +31,19 @@
</message> </message>
<message> <message>
<source>Failed to set star status on article: </source> <source>Failed to set star status on article: </source>
<translation>Échec de la mise en favoris de l'article : </translation> <translation>Échec de la mise en favoris de l&apos;article : </translation>
</message> </message>
<message> <message>
<source>Failed to set read status on article: </source> <source>Failed to set read status on article: </source>
<translation>Échec du passage au statut lu de l'article : </translation> <translation>Échec du passage au statut lu de l&apos;article : </translation>
</message> </message>
<message> <message>
<source>Failed to delete article: </source> <source>Failed to delete article: </source>
<translation>Échec de la suppression de l'article : </translation> <translation>Échec de la suppression de l&apos;article : </translation>
</message>
<message>
<source>Failed to upload article: </source>
<translation type="unfinished"></translation>
</message> </message>
</context> </context>
<context> <context>
@ -43,7 +54,7 @@
</message> </message>
<message> <message>
<source>No articles saved on this server yet</source> <source>No articles saved on this server yet</source>
<translation>Aucun article enregistré sur le serveur pour l'instant</translation> <translation>Aucun article enregistré sur le serveur pour l&apos;instant</translation>
</message> </message>
<message> <message>
<source>Deleting</source> <source>Deleting</source>
@ -55,7 +66,7 @@
</message> </message>
<message> <message>
<source>Show only starred articles</source> <source>Show only starred articles</source>
<translation>Seulement afficher les articles en favoris></translation> <translation>Seulement afficher les articles en favoris&gt;</translation>
</message> </message>
<message> <message>
<source>Show unread articles</source> <source>Show unread articles</source>
@ -65,6 +76,21 @@
<source>Show read articles</source> <source>Show read articles</source>
<translation>Afficher les articles lus</translation> <translation>Afficher les articles lus</translation>
</message> </message>
<message>
<source>Article URL</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add article</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ServerSettings</name>
<message>
<source>Failed to load server settings: </source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ServerSettingsDialog</name> <name>ServerSettingsDialog</name>

View File

@ -41,19 +41,15 @@
<source>Failed to delete article: </source> <source>Failed to delete article: </source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Failed to upload article: </source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ServerPage</name> <name>ServerPage</name>
<message> <message>
<source>Refresh</source> <source>Article URL</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No articles saved on this server yet</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Deleting</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
@ -72,6 +68,22 @@
<source>Show read articles</source> <source>Show read articles</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Refresh</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No articles saved on this server yet</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Deleting</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add article</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>ServerSettings</name> <name>ServerSettings</name>