Version 0.001
This commit is contained in:
parent
1986e59b58
commit
2bc729d02c
77 changed files with 6020 additions and 819 deletions
251
v0.001/source-android/qml/ConfigTab.qml
Normal file
251
v0.001/source-android/qml/ConfigTab.qml
Normal file
|
@ -0,0 +1,251 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Dialogs 1.2
|
||||
import QtQuick.Controls 1.2
|
||||
import "qrc:/js/service.js" as Service
|
||||
import "qrc:/js/layout.js" as Layoutjs
|
||||
import "qrc:/js/helper.js" as Helperjs
|
||||
import "qrc:/qml"
|
||||
|
||||
StackView{
|
||||
id: configStack
|
||||
anchors.fill:parent
|
||||
focus: true
|
||||
Keys.onReleased: if (event.key === Qt.Key_Back && stackView.depth > 1) {
|
||||
stackView.pop(); event.accepted = true;
|
||||
}
|
||||
initialItem: Flickable{
|
||||
width:root.width-5*mm
|
||||
height:root.height-12*mm
|
||||
contentHeight: configBackground.height
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
Rectangle{
|
||||
id:configBackground
|
||||
color: "grey"
|
||||
width:parent.width
|
||||
height:Math.max(80*mm,root.height-12*mm)
|
||||
focus: true
|
||||
|
||||
ComboBox{
|
||||
y:mm
|
||||
width: root.width/2
|
||||
model: ListModel{
|
||||
id: usermodel
|
||||
}
|
||||
onCurrentIndexChanged:{
|
||||
try {Service.readConfig(db,function(obj){
|
||||
servername.text=obj.server;
|
||||
username.text= obj.username;
|
||||
password.text=Qt.atob(obj.password);
|
||||
imagestore.text=obj.imagestore;
|
||||
maxNewsText.text=obj.maxnews;
|
||||
if( obj.isActive==0){isActiveField.text=qsTr("yes")} else {isActiveField.text=qsTr("no")}
|
||||
},"username",currentText)}
|
||||
catch (e){print(e)}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Text {
|
||||
text: "Server"
|
||||
x: 4*mm; y: 10*mm
|
||||
}
|
||||
Text {
|
||||
text: "User"
|
||||
x: 4*mm; y: 20*mm
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Password"
|
||||
x: 4*mm; y: 30*mm
|
||||
}
|
||||
Text {
|
||||
text: "Image dir."
|
||||
x: 4*mm; y: 40*mm
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Max. News"
|
||||
x: 4*mm; y: 50*mm
|
||||
}
|
||||
Text {
|
||||
text: "is Active"
|
||||
x: 4*mm; y: 60*mm
|
||||
}
|
||||
|
||||
Rectangle{color: "white"; x: 25*mm; y: 10*mm; width: root.width/2; height: 5*mm;}
|
||||
Flickable {
|
||||
id: servernameFlickable
|
||||
x: 25*mm; y: 10*mm; width: root.width/2; height: 5*mm;
|
||||
contentWidth: servername.paintedWidth
|
||||
contentHeight: servername.paintedHeight
|
||||
clip: true
|
||||
TextEdit {
|
||||
id: servername
|
||||
width: servernameFlickable.width
|
||||
height: servernameFlickable.height
|
||||
focus: true
|
||||
text:"https://..."
|
||||
//wrapMode: TextEdit.NoWrap
|
||||
//validator: RegExpValidator { regExp: /^(((http|https|ftp):\/\/)?([[a-zA-Z0-9]\-\.])+(\.)([[a-zA-Z0-9]]){2,4}([[a-zA-Z0-9]\/+=%&_\.~?\-]*))*$/}
|
||||
// onEditingFinished:{}
|
||||
onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,servernameFlickable)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle{
|
||||
color: "white"
|
||||
x: 25*mm; y: 20*mm; width: root.width/2; height: 5*mm;
|
||||
TextInput {
|
||||
id: username
|
||||
anchors.fill: parent
|
||||
selectByMouse: true
|
||||
}
|
||||
}
|
||||
Rectangle{
|
||||
color: "white"
|
||||
x: 25*mm; y: 30*mm; width: root.width/2; height: 5*mm;
|
||||
TextInput {
|
||||
id: password
|
||||
anchors.fill: parent
|
||||
selectByMouse: true
|
||||
echoMode: TextInput.PasswordEchoOnEdit
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle{color: "white"; x: 25*mm; y: 40*mm; width: root.width/2-9*mm; height: 5*mm;}
|
||||
Flickable {
|
||||
id: imagestoreFlickable
|
||||
x: 25*mm; y: 40*mm; width: root.width/2-9*mm; height: 5*mm;
|
||||
clip: true
|
||||
TextInput {
|
||||
id: imagestore
|
||||
width: imagestoreFlickable.width
|
||||
height: imagestoreFlickable.height
|
||||
wrapMode: TextEdit.NoWrap
|
||||
onCursorRectangleChanged: Layoutjs.ensureVisibility(cursorRectangle,imagestoreFlickable)
|
||||
}
|
||||
}
|
||||
Slider{ id: maxNews
|
||||
x:37*mm; y: 50*mm;width: root.width/6;height:5*mm
|
||||
minimumValue: 0;maximumValue:100000; stepSize: 1000
|
||||
}
|
||||
Rectangle{color: "white"; x: 25*mm; y: 50*mm; width: 9*mm; height: 5*mm;
|
||||
TextEdit{id:maxNewsText;
|
||||
anchors.fill: parent
|
||||
verticalAlignment:TextEdit.AlignRight
|
||||
text:maxNews.value
|
||||
focus: true
|
||||
selectByMouse: true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Rectangle{
|
||||
x: 25*mm; y: 60*mm; width: root.width/2; height: 5*mm;
|
||||
Text{
|
||||
id: isActiveField
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
|
||||
FileDialog {
|
||||
id: imagestoreDialog
|
||||
title: "Please choose a directory"
|
||||
folder: shortcuts.pictures
|
||||
selectFolder: true
|
||||
onAccepted: {
|
||||
var imagestoreString=imagestoreDialog.folder.toString(); imagestoreString=imagestoreString.replace(/^(file:\/{2})/,"")+"/"
|
||||
imagestore.text=imagestoreString;
|
||||
console.log("You chose: " + imagestoreDialog.folder)
|
||||
}
|
||||
onRejected: {
|
||||
console.log("Canceled")
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
x: root.width/2+18*mm; y: 40*mm; width: 7*mm; height: 5*mm;
|
||||
text: "..."
|
||||
onClicked:
|
||||
{imagestoreDialog.open()}
|
||||
}
|
||||
|
||||
|
||||
Button {
|
||||
x: 25*mm; y: 70*mm; width: implicitWidth; height: implicitHeight;
|
||||
text: "Update"
|
||||
onClicked:{
|
||||
var userconfig={server: servername.text, username: username.text, password:Qt.btoa(password.text), imagestore:imagestore.text,maxnews:maxNewsText.text};
|
||||
var errormessage="";
|
||||
if (servername.text==""){errormessage=qsTr("No server given! ")}
|
||||
//if (!servername.acceptableInput){errormessage+=qsTr("Server name not valid! ")}
|
||||
else if (username.text==""){errormessage+=qsTr("No username given! ")}
|
||||
else if (password.text=="") {errormessage+=qsTr("No password given! ")}
|
||||
else if (imagestore.text=="") {errormessage+=qsTr("No image directory given!")}
|
||||
else if (maxNewsText.text=="") {errormessage+=qsTr("No maximum news number given!")}
|
||||
else {errormessage=""}
|
||||
if (errormessage=="") {Service.storeConfig(db,userconfig);
|
||||
Service.readConfig(db,function(userconfig){Service.getServerConfig(userconfig,configBackground, function(obj){
|
||||
var serverString=obj;
|
||||
var serverconfigObject=Qt.createQmlObject(serverString,configBackground,"serverconfigOutput");
|
||||
usermodel.append({text:username.text});
|
||||
//reset values
|
||||
root.login=userconfig;
|
||||
root.contactlist=[];
|
||||
root.news=[]
|
||||
root.newContacts=[]
|
||||
root.currentContact= 0
|
||||
root.contactLoadType= ""
|
||||
|
||||
root.currentIndex=0;
|
||||
newstab.active=true;
|
||||
})},"isActive",0);
|
||||
//try {newstab.newsModel.clear();
|
||||
//friendstab.friendsModel.clear();
|
||||
//photostab.photogroupModel.clear();} catch(e){}
|
||||
}
|
||||
else {Helperjs.show("Error", errormessage,root)}
|
||||
}}
|
||||
|
||||
Button {
|
||||
x: root.width/2+2*mm; y: mm; width: 5*mm; height: 5*mm;
|
||||
text: "-"
|
||||
onClicked:{
|
||||
var userconfig={server: servername.text, username: username.text, password: Qt.btoa(password.text)};
|
||||
Service.deleteConfig(db,userconfig);
|
||||
}}
|
||||
|
||||
Button {
|
||||
x: root.width/2+8*mm; y: mm; width: 5*mm; height: 5*mm;
|
||||
text: "+"
|
||||
onClicked:{
|
||||
servername.text="https://..."
|
||||
username.text=""
|
||||
password.text=""
|
||||
imagestore.text=""
|
||||
maxNews.value=1000
|
||||
isActiveField.text=""
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
x: root.width/2+14*mm; y: mm; width: 5*mm; height: 5*mm;
|
||||
text: "?"
|
||||
onClicked:{
|
||||
configStack.push({item:"qrc:/qml/InfoBox.qml"});
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
try{Helperjs.readData(db,"config",function(users){
|
||||
users.sort(function(obj1, obj2) {
|
||||
return obj1.isActive - obj2.isActive;
|
||||
});
|
||||
for (var i=0; i<users.length;i++){
|
||||
if (users[i]) {usermodel.append({text:users[i].username});};
|
||||
};})}
|
||||
catch (e){print(e)}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
128
v0.001/source-android/qml/FriendComponent.qml
Normal file
128
v0.001/source-android/qml/FriendComponent.qml
Normal file
|
@ -0,0 +1,128 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.3
|
||||
import "qrc:/js/service.js" as Service
|
||||
import "qrc:/js/layout.js" as Layoutjs
|
||||
|
||||
Item {
|
||||
id: friendComponent
|
||||
property date createdAtDate: new Date(friend.created_at)
|
||||
|
||||
Rectangle {
|
||||
id: wrapper
|
||||
width: 16*mm
|
||||
height: 15*mm
|
||||
border.color: "grey"
|
||||
color:"white"
|
||||
|
||||
Image {
|
||||
id: photoImage
|
||||
x:1
|
||||
y:1
|
||||
width: 10*mm
|
||||
height:10*mm
|
||||
source:"file://"+ friend.profile_image
|
||||
}
|
||||
|
||||
Label {
|
||||
id: namelabel
|
||||
x: 1
|
||||
width: wrapper.width-2
|
||||
elide: Text.ElideRight
|
||||
height: 3*mm
|
||||
text: friend.screen_name
|
||||
anchors.topMargin: 0
|
||||
anchors.left: photoImage.left
|
||||
color: "#303030"
|
||||
font.pixelSize: 3*mm
|
||||
anchors.top: photoImage.bottom
|
||||
}
|
||||
Button{
|
||||
id:infobutton
|
||||
width: 5*mm
|
||||
height: 5*mm
|
||||
text:"?"
|
||||
anchors.left: photoImage.right
|
||||
anchors.leftMargin: 3
|
||||
anchors.topMargin: 3
|
||||
anchors.top: parent.top
|
||||
onClicked:{
|
||||
print("State: "+ friendComponent.state+friendsView.contentY);
|
||||
friendComponent.state="large"}
|
||||
}
|
||||
|
||||
|
||||
Rectangle{
|
||||
id: detailsrectangle
|
||||
anchors.top: namelabel.bottom
|
||||
anchors.topMargin: 2*mm
|
||||
opacity: 0
|
||||
|
||||
Text{
|
||||
id:namelabeltext
|
||||
anchors.top: parent.top
|
||||
width: root.width-10*mm
|
||||
height: namelabeltext.implicitHeight
|
||||
font.pixelSize: 3*mm
|
||||
textFormat:Text.RichText
|
||||
wrapMode: Text.Wrap
|
||||
text:"<b>"+qsTr("Description")+": </b> "+Qt.atob(friend.description)+"<br> <b>"+qsTr("Server Type")+":</b> "+friend.location+"<br> <b>"+qsTr("Posts")+":</b> "+friend.statuses_count+
|
||||
"<br> <b>"+qsTr("URL")+":</b> <a href='"+ friend.url+"'>"+friend.url+"</a><br> <b>"+
|
||||
qsTr("Created at")+":</b> "+createdAtDate.toLocaleString(Qt.locale())
|
||||
onLinkActivated: {
|
||||
Qt.openUrlExternally(link)}
|
||||
}
|
||||
|
||||
Row{
|
||||
anchors.top: namelabeltext.bottom
|
||||
anchors.topMargin: 2*mm
|
||||
spacing:4
|
||||
|
||||
Button{
|
||||
id:photobutton
|
||||
text:"Photos"
|
||||
visible:friend.location=="Friendica"? 1:0
|
||||
onClicked:{root.currentIndex=2;
|
||||
fotostab.active=true;
|
||||
root.fotoSignal(friend) ;
|
||||
}
|
||||
}
|
||||
|
||||
Button{
|
||||
id:messagebutton
|
||||
text:"Messages"
|
||||
onClicked:{root.currentIndex=0;
|
||||
newstab.active=true;
|
||||
root.messageSignal(friend.id) ;
|
||||
}
|
||||
}
|
||||
|
||||
Button{id:dmbutton
|
||||
visible: friend.following=="true"?true:false
|
||||
text: "DM"
|
||||
onClicked:{root.currentIndex=0;
|
||||
newstab.active=true;
|
||||
root.directmessageSignal(friend.screen_name);
|
||||
}
|
||||
}
|
||||
|
||||
Button{
|
||||
id: closeButton
|
||||
text: "close"
|
||||
onClicked:{friendComponent.state=""}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "large"
|
||||
PropertyChanges { target: namelabel; font.pixelSize: 4*mm; width:friendsView.width; text:Qt.atob(friend.name)+" (@"+friend.screen_name+")"}
|
||||
PropertyChanges { target: friendComponent; z: 2 }
|
||||
PropertyChanges { target: wrapper; width:friendsView.width;height:friendsView.height -2*mm-1}
|
||||
PropertyChanges { target: photoImage; width:15*mm;height:15*mm }
|
||||
PropertyChanges { target:friendComponent.GridView.view ;contentY:friendComponent.y;contentX:friendComponent.x;interactive:false}
|
||||
PropertyChanges { target: detailsrectangle; opacity:1 }
|
||||
}
|
||||
]
|
||||
}
|
66
v0.001/source-android/qml/FriendsTab.qml
Normal file
66
v0.001/source-android/qml/FriendsTab.qml
Normal file
|
@ -0,0 +1,66 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Dialogs 1.2
|
||||
import QtQuick.Controls 1.2
|
||||
import "qrc:/js/service.js" as Service
|
||||
import "qrc:/js/helper.js" as Helperjs
|
||||
import "qrc:/js/news.js" as Newsjs
|
||||
import "qrc:/qml"
|
||||
|
||||
Rectangle {
|
||||
function showFriends(username){try {friendsModel.clear()} catch(e){print(e)};
|
||||
Helperjs.readData(db, "contacts",function(friendsobject){
|
||||
for (var j=0;j<friendsobject.length;j++){
|
||||
friendsModel.append({"friend":friendsobject[j]});
|
||||
}},"username", username)
|
||||
}
|
||||
|
||||
color: "white"
|
||||
Button {
|
||||
id: updateFriendsButton
|
||||
text: qsTr("Update")
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
onClicked: {
|
||||
try {friendsModel.clear()} catch(e){print(e)};
|
||||
root.contactLoadType="friends";
|
||||
Newsjs.requestFriends(root.login,db,root,function(nc){
|
||||
root.newContacts=nc
|
||||
})}
|
||||
}
|
||||
ProgressBar{
|
||||
id: newContactsProgress
|
||||
width: 15*mm
|
||||
height: updateFriendsButton.height
|
||||
anchors.top: parent.top
|
||||
anchors.right:updateFriendsButton.left
|
||||
anchors.rightMargin:mm
|
||||
visible: (root.currentContact!=root.newContacts.length)?true:false
|
||||
value: root.currentContact/root.newContacts.length
|
||||
}
|
||||
|
||||
Rectangle{
|
||||
x: 2*mm; y:updateFriendsButton.height+2*mm
|
||||
width:root.width-5*mm
|
||||
height:root.height-5*mm
|
||||
GridView {
|
||||
id: friendsView
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: 12*mm
|
||||
clip: true
|
||||
cellHeight: 16*mm
|
||||
cellWidth: 17*mm
|
||||
add: Transition {
|
||||
NumberAnimation { properties: "x,y"; from: 300; duration: 1000 }
|
||||
}
|
||||
model: friendsModel
|
||||
delegate: FriendComponent { }
|
||||
}
|
||||
}
|
||||
ListModel{
|
||||
id: friendsModel
|
||||
}
|
||||
Component.onCompleted: {
|
||||
root.friendsSignal.connect(showFriends);
|
||||
showFriends(login.username)
|
||||
}
|
||||
}
|
22
v0.001/source-android/qml/InfoBox.qml
Normal file
22
v0.001/source-android/qml/InfoBox.qml
Normal file
|
@ -0,0 +1,22 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.2
|
||||
Rectangle{
|
||||
color:"white"
|
||||
width:infoBoxText.contentWidth
|
||||
height:infoBoxText.contentHeight
|
||||
Text{id:infoBoxText
|
||||
textFormat: Text.RichText
|
||||
wrapMode: Text.Wrap
|
||||
text: "<b>Friendiqa v0.001 </b><br>Licensed under GPL 3<br> "+
|
||||
"Sourcecode: <a href='https://github.com/LubuWest/Friendiqa'>https://github.com/LubuWest/Friendica</a><br>"+
|
||||
"C++ code by <a href='https://kirgroup.com/profile/fabrixxm'>Fabio</a><br>"+
|
||||
"QML and Javascript code by <a href='https://freunde.ma-nic.de/profile/marco'>Marco</a>"
|
||||
onLinkActivated:{
|
||||
Qt.openUrlExternally(link)}
|
||||
}
|
||||
Button{
|
||||
text:qsTr("Close")
|
||||
onClicked:{configStack.pop()}
|
||||
anchors.top:infoBoxText.bottom
|
||||
}
|
||||
}
|
132
v0.001/source-android/qml/MessageSend.qml
Normal file
132
v0.001/source-android/qml/MessageSend.qml
Normal file
|
@ -0,0 +1,132 @@
|
|||
// message.qml
|
||||
// message with buttons
|
||||
import QtQuick 2.0
|
||||
import QtQml 2.2
|
||||
import QtQuick.Controls 1.3
|
||||
import QtQuick.Dialogs 1.2
|
||||
import QtQuick.LocalStorage 2.0
|
||||
//import "../qml"
|
||||
import "qrc:/js/service.js" as Service
|
||||
|
||||
Item{
|
||||
id:messageSend
|
||||
property var login
|
||||
property string parentId: ""
|
||||
property string reply_to_user:""
|
||||
property string attachImageURL: "";
|
||||
property int directmessage: 0;
|
||||
property var contacts: []
|
||||
// title: parentId !== "" ? qsTr("Reply to "+reply_to_user) : qsTr("New post")
|
||||
|
||||
function statusUpdate(title,status,in_reply_to_status_id,attachImageURL) {
|
||||
xhr.url= login.server + "/api/statuses/update.xml";
|
||||
xhr.setLogin(login.username+":"+Qt.atob(login.password));
|
||||
print("login: "+login.username+":"+Qt.atob(login.password));
|
||||
xhr.clearParams();
|
||||
xhr.setParam("source", "Friendiqa");
|
||||
xhr.setParam("status", status);
|
||||
if (parentId!="") {xhr.setParam("in_reply_to_status_id", parentid)};
|
||||
if (title!=="") {xhr.setParam("title", title)};
|
||||
if (attachImageURL!=="") {xhr.setImageFileParam("media", attachImageURL )};
|
||||
xhr.post();
|
||||
}
|
||||
|
||||
function dmUpdate(title,text,replyto,screen_name,attachImageURL) {
|
||||
xhr.url= login.server + "/api/direct_messages/new.xml";
|
||||
xhr.setLogin(login.username+":"+Qt.atob(login.password));
|
||||
xhr.clearParams();
|
||||
xhr.setParam("text", text);
|
||||
xhr.setParam("screen_name", screen_name);
|
||||
if (parentId!="") {xhr.setParam("replyto", replyto)};
|
||||
if (title!=="") {xhr.setParam("title", title)};
|
||||
if (attachImageURL!=="") {xhr.setImageFileParam("media", attachImageURL )};
|
||||
xhr.post();
|
||||
}
|
||||
|
||||
Column {
|
||||
id:messageColumn
|
||||
spacing: 2
|
||||
|
||||
TextField {
|
||||
id: titleField
|
||||
width: parent.width
|
||||
placeholderText: qsTr("Title (optional)")
|
||||
visible: messageSend.parentId === ""
|
||||
}
|
||||
|
||||
TextArea {
|
||||
id: bodyField
|
||||
width: parent.width
|
||||
height: 30*mm
|
||||
wrapMode: TextEdit.Wrap
|
||||
}
|
||||
CheckBox{
|
||||
id:dmCheckbox
|
||||
text:"DM"
|
||||
enabled: false
|
||||
checked: (directmessage==1)?true:false
|
||||
onClicked:{
|
||||
if(dmCheckbox.checkedState==Qt.Checked){directmessage=1}
|
||||
else if(dmCheckbox.checkedState==Qt.Unchecked){directmessage=0}
|
||||
}
|
||||
}
|
||||
Row{
|
||||
spacing:2
|
||||
Button {
|
||||
id: cancelButton
|
||||
text: qsTr("Cancel")
|
||||
onClicked: {newsStack.pop()}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: attachButton
|
||||
text: qsTr("Attach")
|
||||
onClicked: {imageAttachmentDialog.open()}
|
||||
}
|
||||
Button{
|
||||
id:contactButton
|
||||
text:qsTr("cc")
|
||||
visible:(directmessage==0)
|
||||
onClicked:{
|
||||
var contactitems="";
|
||||
for (var i=0;i<contacts.length;i++){
|
||||
contactitems=contactitems+"MenuItem{text:'"+contacts[i]+"'; onTriggered: bodyField.append(' @"+contacts[i]+"')}"
|
||||
}
|
||||
var menuString="import QtQuick.Controls 1.4; Menu {"+contactitems+"}";
|
||||
// print(menuString);
|
||||
var contactlistObject=Qt.createQmlObject(menuString,messageSend,"contactmenuOutput")
|
||||
contactlistObject.popup() }
|
||||
}
|
||||
|
||||
Button {
|
||||
id: sendButton
|
||||
text: qsTr("Send")
|
||||
onClicked: {
|
||||
print("login: "+login.server+login.username);
|
||||
if (directmessage==0){
|
||||
statusUpdate(titleField.text,bodyField.text,messageSend.parentId,attachImageURL.toString());}
|
||||
else {dmUpdate( titleField.text,bodyField.text,"",messageSend.reply_to_user) }
|
||||
newsStack.pop()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FileDialog {
|
||||
id: imageAttachmentDialog
|
||||
title: "Please choose a picture"
|
||||
folder: shortcuts.pictures
|
||||
selectFolder: false
|
||||
onAccepted: {
|
||||
attachImageURL=imageAttachmentDialog.fileUrl;
|
||||
var imageAttachementObject=Qt.createQmlObject('import QtQuick 2.0; Image {source:"'+attachImageURL.toString()+'"; width: 30*mm; height: 30*mm;fillMode: Image.PreserveAspectFit}',messageColumn,"attachedImage");
|
||||
console.log("You chose: " + attachImageURL)
|
||||
|
||||
}
|
||||
onRejected: {
|
||||
console.log("Canceled")
|
||||
}
|
||||
}
|
||||
}
|
154
v0.001/source-android/qml/NewsTab.qml
Normal file
154
v0.001/source-android/qml/NewsTab.qml
Normal file
|
@ -0,0 +1,154 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Dialogs 1.2
|
||||
import QtQuick.Controls 1.2
|
||||
import QtQuick.LocalStorage 2.0 as Sql
|
||||
import "qrc:/js/news.js" as Newsjs
|
||||
import "qrc:/js/helper.js" as Helperjs
|
||||
|
||||
Item {
|
||||
property string newstabStatus:"news"
|
||||
|
||||
function showNews(newsToShow){
|
||||
newsBusy.running=false;
|
||||
var currentTime= new Date();
|
||||
var msg = {'currentTime': currentTime, 'model': newsModel,'news':newsToShow};
|
||||
newsWorker.sendMessage(msg);
|
||||
}
|
||||
|
||||
function onFriendsMessages(friend){print(" Friend "+friend);
|
||||
newstabStatus="friendmessage";
|
||||
Newsjs.newsfromdb(db,root.login.username, function(dbnews){showNews(dbnews)},friend)
|
||||
}
|
||||
|
||||
function onDirectMessage(friend){
|
||||
newsStack.push({item:"qrc:/qml/MessageSend.qml",properties:{"reply_to_user": friend,"directmessage":1,"login":root.login}});
|
||||
}
|
||||
|
||||
function cleanNews(database){
|
||||
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||
db.transaction( function(tx) {
|
||||
var maxnewsrs = tx.executeSql("SELECT DISTINCT maxnews FROM config");
|
||||
var maxnews=maxnewsrs.rows.item(0);
|
||||
var newscountrs = tx.executeSql('SELECT COUNT(*) from news');
|
||||
var newscount = newscountrs.rows.item(0);
|
||||
if (newscount>maxnews){var lastvalidtimers= tx.executeSql('select created_at from news ORDER BY created_at DESC LIMIT ' +(newscount-maxnews));
|
||||
var lastvalidtime=lastvalidtimers.rows.item(-1);
|
||||
var deleters = tx.executeSql('DELETE from news WHERE created_at<'+lastvalidtime)}
|
||||
});
|
||||
Qt.quit()
|
||||
}
|
||||
|
||||
StackView{
|
||||
id: newsStack
|
||||
anchors.fill:parent
|
||||
focus: true
|
||||
Keys.onReleased: if (event.key === Qt.Key_Back && stackView.depth > 1) {
|
||||
stackView.pop(); event.accepted = true;
|
||||
}
|
||||
initialItem:Rectangle {
|
||||
color: "white"
|
||||
width:root.width-2*mm
|
||||
height:root.height-8*mm
|
||||
|
||||
Button {
|
||||
id: newMessageButton
|
||||
text: qsTr("+")
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
onClicked: {
|
||||
Helperjs.readField("screen_name",root.db,"contacts",root.login.username,function(friends){
|
||||
newsStack.push({item:"qrc:/qml/MessageSend.qml",properties:{"contacts": friends,"login":root.login}})
|
||||
},"isFriend",1);
|
||||
}
|
||||
}
|
||||
Button {
|
||||
id: quitButton
|
||||
text: qsTr("Quit")
|
||||
anchors.top: parent.top
|
||||
anchors.right: newMessageButton.left
|
||||
onClicked: {cleanNews(root.db)}
|
||||
}
|
||||
|
||||
Component { id:footerComponent
|
||||
Rectangle{
|
||||
border.color: "#EEEEEE"
|
||||
border.width: 1
|
||||
width:parent.width
|
||||
height:6*mm
|
||||
Text{
|
||||
font.pixelSize: 1.5*mm
|
||||
anchors.centerIn: parent
|
||||
text:qsTr("More")
|
||||
}
|
||||
MouseArea{anchors.fill:parent
|
||||
onClicked:{
|
||||
var currentTime= new Date();
|
||||
if(newstabStatus=="news"){
|
||||
var lastnews_id=newsModel.get(newsModel.count-1).newsitemobject.created_at;
|
||||
Newsjs.newsfromdb(root.db,root.login.username, function(news){
|
||||
var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true};
|
||||
newsWorker.sendMessage(msg);
|
||||
},false,lastnews_id)}
|
||||
else if(newstabStatus=="friendmessage"){
|
||||
Newsjs.newsfromdb(root.db,root.login.username, function(news){
|
||||
var msg = {'currentTime': currentTime, 'model': newsModel,'news':news,'appendnews':true};
|
||||
newsWorker.sendMessage(msg);
|
||||
},newsModel.get(newsModel.count-1).newsitemobject.uid,newsModel.get(newsModel.count-1).newsitemobject.created_at)}
|
||||
}}
|
||||
}
|
||||
}
|
||||
ListView {
|
||||
id: newsView
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 8*root.mm
|
||||
anchors.leftMargin: 3*root.mm; anchors.rightMargin: root.mm
|
||||
anchors.bottomMargin: 1*root.mm
|
||||
clip: true
|
||||
spacing: 0
|
||||
footer: footerComponent
|
||||
model: newsModel
|
||||
delegate: Newsitem{}
|
||||
}
|
||||
|
||||
ListModel{id: newsModel}
|
||||
|
||||
WorkerScript {
|
||||
id: newsWorker
|
||||
source: "qrc:/js/newsworker.js"
|
||||
}
|
||||
|
||||
Button {
|
||||
id: update
|
||||
anchors.top: parent.top
|
||||
anchors.right: quitButton.left
|
||||
text: "Update"
|
||||
onClicked: { //try{newsModel.clear()} catch(e){}
|
||||
newsBusy.running=true;
|
||||
root.contactLoadType="news";
|
||||
Newsjs.getFriendsTimeline(login,db,contactlist,newstab,function(ns,nc){
|
||||
root.news=ns;root.newContacts=nc;root.currentContact=0;
|
||||
if (ns.length==0){
|
||||
Newsjs.getDirectMessage(root.login,root.db,root,function(dbnews){showNews(dbnews)});
|
||||
newsBusy.running=false}
|
||||
})}
|
||||
}
|
||||
BusyIndicator{
|
||||
id: newsBusy
|
||||
anchors.centerIn:update
|
||||
//anchors.right: update.left
|
||||
//anchors.top:parent.top
|
||||
width:7*mm
|
||||
height: 7*mm
|
||||
}
|
||||
Component.onCompleted: {
|
||||
root.messageSignal.connect(onFriendsMessages);
|
||||
root.directmessageSignal.connect(onDirectMessage);
|
||||
root.newsSignal.connect(showNews);
|
||||
try{newsModel.clear()} catch(e){}
|
||||
Newsjs.newsfromdb(root.db,root.login.username, function(dbnews){
|
||||
showNews(dbnews)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
261
v0.001/source-android/qml/Newsitem.qml
Normal file
261
v0.001/source-android/qml/Newsitem.qml
Normal file
|
@ -0,0 +1,261 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.LocalStorage 2.0
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import "qrc:/js/news.js" as Newsjs
|
||||
import "qrc:/js/layout.js" as Layoutjs
|
||||
|
||||
|
||||
Item {
|
||||
id: newsitem
|
||||
width: newsView.width
|
||||
height:Math.max((itemMessage.height+createdAtLabel.height+4*mm),profileImage.height+user_name.height+mm)
|
||||
property bool show_full: false
|
||||
property string conversation_id: ""
|
||||
property string attachments:""
|
||||
property string attending: ""
|
||||
onAttendingChanged: {attendLabel.visible=true;
|
||||
attendLabel.text= qsTr("attending: ")+ qsTr(attending)}
|
||||
signal replyto(string parent_id)
|
||||
|
||||
Rectangle{width:newsitem.width; height: 1; anchors.bottom: newsitem.bottom; color:"light grey"}
|
||||
|
||||
Rectangle{
|
||||
width:newsitem.width
|
||||
height:newsitem.height-1
|
||||
color: (newsitemobject.directmessage)?"#ffe6e6" : "white"
|
||||
|
||||
Column {
|
||||
id: authorcolumn
|
||||
width: 8*mm
|
||||
|
||||
Image {
|
||||
id:profileImage
|
||||
source: "file://"+newsitemobject.user.profile_image
|
||||
x:1
|
||||
width: 7*mm
|
||||
height: 7*mm
|
||||
MouseArea{
|
||||
anchors.fill: parent
|
||||
onPressAndHold: { newsmenu.popup()}
|
||||
}
|
||||
onStatusChanged: if (profileImage.status == Image.Error) {source="qrc:/images/defaultcontact.jpg"}
|
||||
}
|
||||
Label {
|
||||
id:user_name
|
||||
color: "grey"
|
||||
//height:3.5*mm
|
||||
width:parent.width
|
||||
font.pixelSize: 1.5*mm
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
text: Qt.atob(newsitemobject.user.name)
|
||||
}
|
||||
}
|
||||
Column {
|
||||
id:newscolumn
|
||||
anchors.left: authorcolumn.right
|
||||
|
||||
Row{
|
||||
spacing: 5
|
||||
Label {
|
||||
color: "grey"
|
||||
text: if (newsitemobject.messagetype==0){qsTr("Source: ")+newsitemobject.source
|
||||
} else if (newsitemobject.messagetype==1){ qsTr("Direct Message")} else {" Notification"}
|
||||
font.pixelSize: 1.5*mm
|
||||
}
|
||||
Label {
|
||||
id:createdAtLabel
|
||||
color: "grey"
|
||||
height:3.5*mm
|
||||
font.pixelSize: 1.5*mm
|
||||
horizontalAlignment: Label.AlignRight
|
||||
text: dateDiff
|
||||
}
|
||||
CheckBox {
|
||||
id:favoritedCheckbox
|
||||
style: CheckBoxStyle {
|
||||
background: Rectangle {
|
||||
implicitWidth: 6*mm
|
||||
implicitHeight:2*mm
|
||||
color:"white"
|
||||
}
|
||||
indicator:
|
||||
Rectangle{x:3*mm
|
||||
width: 3*mm
|
||||
implicitHeight:2*mm
|
||||
Text{
|
||||
anchors.centerIn: parent
|
||||
color:control.checked?"black":"grey"
|
||||
text:"\u2605"
|
||||
}}
|
||||
}
|
||||
checked:(newsitemobject.favorited>0)
|
||||
Text{
|
||||
anchors.left: parent.right
|
||||
color: "grey"
|
||||
font.pixelSize: 1.5*mm
|
||||
text: (newsitemobject.favorited>0)? newsitemobject.favorited+qsTr(" Favorites"):""
|
||||
}
|
||||
onClicked:{
|
||||
if(favoritedCheckbox.checkedState==Qt.Checked)
|
||||
{Newsjs.favorite(login,true,newsitemobject.status_id,root)}
|
||||
else
|
||||
if(favoritedCheckbox.checkedState==Qt.Unchecked)
|
||||
{Newsjs.favorite(login,false,newsitemobject.status_id,root)}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Text {
|
||||
color: "#404040"
|
||||
linkColor: "light green"
|
||||
id: itemMessage
|
||||
textFormat: Text.RichText
|
||||
text: Qt.atob(newsitemobject.statusnet_html)
|
||||
width: newsitem.width-8*mm-2
|
||||
height: implicitHeight
|
||||
wrapMode: Text.Wrap
|
||||
onLinkActivated:{ print("link "+link);
|
||||
Qt.openUrlExternally(link)}
|
||||
}
|
||||
Row {
|
||||
CheckBox{id:likeCheckbox
|
||||
height:3*mm
|
||||
width:8*mm
|
||||
style: CheckBoxStyle {
|
||||
background: Rectangle {
|
||||
implicitWidth: 7*mm
|
||||
implicitHeight: 3*mm
|
||||
color:"white"
|
||||
}
|
||||
indicator:
|
||||
Rectangle{
|
||||
implicitWidth: 3*mm
|
||||
implicitHeight:3*mm
|
||||
color:control.checked?"yellow":"white"
|
||||
x: 5*mm
|
||||
Text{
|
||||
font.pixelSize: 1.5*mm
|
||||
color:"grey"
|
||||
text:":-)"
|
||||
}}
|
||||
}
|
||||
onClicked: {
|
||||
if(likeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"like",newsitemobject.status_id,root);dislikeCheckbox.checked=false}
|
||||
else{Newsjs.like(root.login,root.db,0,"like",newsitemobject.status_id,root)}}
|
||||
}
|
||||
CheckBox{id: dislikeCheckbox
|
||||
height:3*mm
|
||||
width:8*mm
|
||||
style: CheckBoxStyle {
|
||||
background: Rectangle {
|
||||
implicitWidth: 7*mm
|
||||
implicitHeight:3*mm
|
||||
color:"white"
|
||||
}
|
||||
indicator:
|
||||
Rectangle{
|
||||
implicitWidth: 3*mm
|
||||
implicitHeight:3*mm
|
||||
color:control.checked?"yellow":"white"
|
||||
x:5*mm
|
||||
Text{
|
||||
font.pixelSize: 1.5*mm
|
||||
color:"grey"
|
||||
text:":-("
|
||||
}}
|
||||
}
|
||||
onClicked: {
|
||||
if (dislikeCheckbox.checked==true){Newsjs.like(root.login,root.db,1,"dislike",newsitemobject.status_id);likeCheckbox.checked=false}
|
||||
else {Newsjs.like(root.login,root.db,0,"dislike",newsitemobject.status_id,root)}}
|
||||
}
|
||||
Label {
|
||||
id:replytoLabel
|
||||
color: "grey"
|
||||
height:3.5*mm
|
||||
font.pixelSize: 1.5*mm
|
||||
horizontalAlignment: Label.AlignRight
|
||||
text: try {qsTr("In reply to ")+newsitemobject.reply_user.screen_name
|
||||
}catch(e){" "}
|
||||
}
|
||||
Label {
|
||||
id:attendLabel
|
||||
visible: false
|
||||
color: "grey"
|
||||
height:3.5*mm
|
||||
font.pixelSize: 1.5*mm
|
||||
horizontalAlignment: Label.AlignRight
|
||||
text: qsTr("attending: ")+ qsTr(attending)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Menu {
|
||||
id:newsmenu
|
||||
MenuItem {
|
||||
text: qsTr("Reply")
|
||||
onTriggered: {
|
||||
newsStack.push({item:"qrc:/qml/MessageSend.qml",properties:{"reply_to_user": newsitemobject.user.screen_name,"parentId":newsitemobject.status_id}});
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("DM")
|
||||
onTriggered: {
|
||||
root.directmessageSignal(newsitemobject.user.screen_name);
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Repost")
|
||||
onTriggered: {
|
||||
Newsjs.retweetNews(root.login,db,newsitemobject.status_id,root,function(reply){
|
||||
print(reply);
|
||||
})
|
||||
}
|
||||
}
|
||||
MenuItem {
|
||||
text: qsTr("Conversation")
|
||||
onTriggered: {
|
||||
Newsjs.requestConversation(root.login,db,newsitemobject.status_id,root,function(){
|
||||
var currentTime= new Date();
|
||||
Newsjs.conversationfromdb(db,root.login.username,newsitemobject.statusnet_conversation_id, function(newsarray){
|
||||
newsModel.clear();
|
||||
var msg = {'currentTime': currentTime, 'model': newsModel,'news':newsarray,'latestmessage':0};
|
||||
newsWorker.sendMessage(msg);
|
||||
});
|
||||
}
|
||||
)}
|
||||
}
|
||||
|
||||
Menu{
|
||||
title: qsTr("Attending")
|
||||
|
||||
MenuItem{text:qsTr("yes")
|
||||
onTriggered: {Newsjs.attend(root.login,db,"yes",newsitemobject.status_id,root,function(){
|
||||
newsitem.attending="yes";
|
||||
attendLabel.visible=true})}
|
||||
}
|
||||
|
||||
MenuItem{text:qsTr("maybe")
|
||||
onTriggered: {Newsjs.attend(root.login,db,"maybe",newsitemobject.status_id,root,function(){
|
||||
newsitem.attending="maybe"})}
|
||||
}
|
||||
|
||||
MenuItem{text:qsTr("no")
|
||||
onTriggered: {Newsjs.attend(root.login,db,"no",newsitemobject.status_id,root,function(){
|
||||
newsitem.attending="no"})}
|
||||
}
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: qsTr("Delete")
|
||||
onTriggered: {
|
||||
Newsjs.deleteNews(root.login,db,newsitemobject.status_id,root,function(reply){
|
||||
print(JSON.stringify(reply));
|
||||
newsModel.remove(index);
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
100
v0.001/source-android/qml/PhotoComponent.qml
Normal file
100
v0.001/source-android/qml/PhotoComponent.qml
Normal file
|
@ -0,0 +1,100 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.LocalStorage 2.0
|
||||
import QtQuick.Controls 1.2
|
||||
|
||||
Package {
|
||||
Item { id: stackItem; Package.name: 'stack'; z: stackItem.PathView.z;width:16.5*mm;height:16.5*mm}
|
||||
Item { id: listItem; Package.name: 'list'; width: root.width-1*mm; height: root.height-8*mm; }
|
||||
Item { id: gridItem; Package.name: 'grid';}
|
||||
|
||||
Item {
|
||||
id: photoWrapper
|
||||
width: 16.5*mm; height: 16.5*mm
|
||||
z: stackItem.PathView.z
|
||||
property string hqphotolink: photoLink
|
||||
|
||||
Rectangle {
|
||||
id: placeHolder
|
||||
color: 'lightblue'; antialiasing: true
|
||||
anchors.fill:parent
|
||||
//width: parent.width; height: parent.height;
|
||||
}
|
||||
|
||||
BusyIndicator { anchors.centerIn: parent; running: realImage.status != Image.Ready }
|
||||
Image {
|
||||
id: realImage;
|
||||
// property string hqphotolink: photoLink
|
||||
width: photoWrapper.width; height: photoWrapper.height
|
||||
antialiasing: true;
|
||||
asynchronous: true
|
||||
cache: false
|
||||
fillMode: Image.PreserveAspectFit;
|
||||
source: imageLocation
|
||||
// onStatusChanged: if (realImage.status == Image.Ready) print(realImage.paintedHeight+"x"+realImage.paintedWidth)
|
||||
}
|
||||
Rectangle{
|
||||
id:phototextRectangle
|
||||
color:"black"
|
||||
z:3
|
||||
opacity: 0.5
|
||||
width:phototext.contentWidth
|
||||
height: phototext.contentHeight
|
||||
anchors.bottom: photoWrapper.bottom
|
||||
}
|
||||
Text {
|
||||
id:phototext
|
||||
z:4
|
||||
text: photoDescription.trim()
|
||||
width:15*mm
|
||||
anchors.bottom: photoWrapper.bottom
|
||||
color: "white"
|
||||
font.pixelSize: 2*mm
|
||||
wrapMode:Text.Wrap
|
||||
}
|
||||
MouseArea {
|
||||
width: realImage.paintedWidth; height: realImage.paintedHeight; anchors.centerIn: realImage
|
||||
onClicked: {
|
||||
if (albumWrapper.state == 'inGrid') {
|
||||
gridItem.GridView.view.currentIndex = index;
|
||||
//print("photoLink"+realImage.photoLink)
|
||||
albumWrapper.state = 'fullscreen'
|
||||
} else {
|
||||
gridItem.GridView.view.currentIndex = index;
|
||||
albumWrapper.state = 'inGrid'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: 'stacked'; when: albumWrapper.state == ''
|
||||
ParentChange { target: photoWrapper; parent: stackItem; }//x: 1*mm; y: 1*mm }
|
||||
PropertyChanges { target: photoWrapper; opacity: stackItem.PathView.onPath ? 1.0 : 0.0 }
|
||||
PropertyChanges { target: phototext; opacity: 0.0 }
|
||||
PropertyChanges { target: phototextRectangle; opacity: 0.0 }
|
||||
},
|
||||
State {
|
||||
name: 'inGrid'; when: albumWrapper.state == 'inGrid'
|
||||
ParentChange { target: photoWrapper; parent: gridItem; x: 1*mm; y: 1*mm;}
|
||||
PropertyChanges { target: phototext; opacity: 1.0 }
|
||||
PropertyChanges { target: phototextRectangle; opacity: 0.5 }
|
||||
PropertyChanges { target: placeHolder; opacity: 1.0 }
|
||||
},
|
||||
State {
|
||||
name: 'fullscreen'; when: albumWrapper.state == 'fullscreen'
|
||||
ParentChange {
|
||||
target: photoWrapper; parent: listItem; x: 1; y: 1;
|
||||
width: root.width-mm; height: root.heigh-8*mm
|
||||
}
|
||||
PropertyChanges { target: placeHolder; opacity: 0.0 }
|
||||
PropertyChanges { target: realImage; source: photoWrapper.hqphotolink}
|
||||
PropertyChanges { target: phototext; anchors.bottom: realImage.bottom}
|
||||
PropertyChanges { target: phototext; width:realImage.width }
|
||||
PropertyChanges { target: phototextRectangle; anchors.bottom: realImage.bottom }
|
||||
PropertyChanges { target: realImage; width: Math.min(listItem.width,sourceSize.width);height: Math.min(listItem.height,sourceSize.height) }
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
}
|
||||
|
26
v0.001/source-android/qml/PhotoPlaceholder.qml
Normal file
26
v0.001/source-android/qml/PhotoPlaceholder.qml
Normal file
|
@ -0,0 +1,26 @@
|
|||
import QtQuick 2.0
|
||||
import "qrc:/js/helper.js" as Helperjs
|
||||
|
||||
Image {
|
||||
id:photoPlaceholder
|
||||
property string imageName:"x.jpg"
|
||||
property string downloadtype:""
|
||||
fillMode: Image.PreserveAspectFit
|
||||
onStatusChanged: {
|
||||
if (photoPlaceholder.status == Image.Ready) {
|
||||
//print("Photo width"+width+" height"+height+" Ratio "+ fillMode);
|
||||
var saveprocess=photoPlaceholder.grabToImage(function(result){
|
||||
var saveresult=result.saveToFile(imageName.toString());
|
||||
if (saveresult){
|
||||
if ((downloadtype=="picture")&&(newImages.length>0)){
|
||||
photoPlaceholder.destroy();
|
||||
currentImageNo=currentImageNo+1
|
||||
}
|
||||
else if ((downloadtype=="contact")&&(root.newContacts.length>0))
|
||||
{
|
||||
photoPlaceholder.destroy(100);
|
||||
root.currentContact=root.currentContact+1
|
||||
}
|
||||
}});
|
||||
}}}
|
||||
|
135
v0.001/source-android/qml/PhotoTab.qml
Normal file
135
v0.001/source-android/qml/PhotoTab.qml
Normal file
|
@ -0,0 +1,135 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Dialogs 1.2
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQml.Models 2.1
|
||||
import "qrc:/js/service.js" as Service
|
||||
import "qrc:/js/helper.js" as Helperjs
|
||||
import "qrc:/qml"
|
||||
|
||||
Rectangle {
|
||||
id:fotorectangle
|
||||
width:root.width-mm
|
||||
height:root.height-5*mm
|
||||
color: '#fff'
|
||||
property var newImages:[]
|
||||
property int currentImageNo: 0
|
||||
//onLoginChanged:{var msg = {'model': photogroupModel,'albums':[],'firstalbum':0,'foreignPicture':false};
|
||||
// photoWorker.sendMessage(msg);
|
||||
//}
|
||||
onNewImagesChanged:{if(newImages.length>0){ Service.dataRequest(root.login,newImages[currentImageNo],root.db,fotorectangle);newImagesProgress.visible=true //download first image
|
||||
} }
|
||||
onCurrentImageNoChanged:{ if(currentImageNo<newImages.length){Service.dataRequest(root.login,newImages[currentImageNo],root.db,fotorectangle)};
|
||||
if(currentImageNo==newImages.length){newImagesProgress.visible=false;showOwnFotos();
|
||||
newImages=[];currentImageNo=0}
|
||||
// download next image if photoplaceholder is finished saving
|
||||
}
|
||||
|
||||
|
||||
ProgressBar{
|
||||
id: newImagesProgress
|
||||
width: 15*mm
|
||||
height: updatePhotolist.height
|
||||
anchors.top: parent.top
|
||||
anchors.right:updatePhotolist.left
|
||||
anchors.rightMargin:mm
|
||||
visible: false
|
||||
value: currentImageNo/newImages.length
|
||||
}
|
||||
|
||||
Button{
|
||||
id: updatePhotolist
|
||||
anchors.top: parent.top
|
||||
anchors.right:showFotos.left
|
||||
anchors.rightMargin:mm
|
||||
text: qsTr("Update")
|
||||
onClicked: {
|
||||
Service.requestList(root.login,root.db, fotostab,function(obj){
|
||||
newImages=obj;
|
||||
})}}
|
||||
|
||||
Button{
|
||||
id: showFotos
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin:2*mm
|
||||
text: qsTr("Show")
|
||||
onClicked: {showOwnFotos()}
|
||||
}
|
||||
|
||||
DelegateModel{
|
||||
id: visualphotoModel
|
||||
delegate: PhotogroupComponent{}
|
||||
model: photogroupModel
|
||||
}
|
||||
|
||||
ListModel{
|
||||
id: photogroupModel
|
||||
}
|
||||
|
||||
GridView {
|
||||
id: albumgridview
|
||||
cellWidth: 17*mm
|
||||
cellHeight: 17*mm
|
||||
x: mm;y:8*mm
|
||||
width: parent.width-2*mm; height: parent.height-9*mm
|
||||
clip: true
|
||||
model: visualphotoModel.parts.album
|
||||
footer:
|
||||
Rectangle{
|
||||
border.color: "#EEEEEE"
|
||||
border.width: 1
|
||||
width:12*mm
|
||||
height:6*mm
|
||||
Text{
|
||||
font.pixelSize: 1.5*mm
|
||||
anchors.centerIn: parent
|
||||
text:qsTr("More")
|
||||
}
|
||||
MouseArea{anchors.fill:parent
|
||||
onClicked:{
|
||||
var lastalbum_id=photogroupModel.get(photogroupModel.count-1);
|
||||
if(photogroupModel.get(photogroupModel.count-1).foreignPictures==false){Service.requestFriendsAlbumPictures(friend,fotostab,function(albums){
|
||||
var msg = {'model': photogroupModel,'albums':albums,'firstalbum':lastalbum_id+1,'foreignPicture':true};
|
||||
photoWorker.sendMessage(msg); })}
|
||||
else { Helperjs.readField("album",root.db, "imageData",root.login.username,function(albums){
|
||||
var msg = { 'model': photogroupModel,'albums':albums,'foreignPicture': false,'firstalbum':lastalbum_id+1};
|
||||
photoWorker.sendMessage(msg)})}
|
||||
}}}
|
||||
}
|
||||
|
||||
Rectangle { id: photoBackground; color: 'light grey'; width: parent.width; height: parent.height; opacity: 0; visible: opacity != 0.0 }
|
||||
|
||||
ListView { anchors.fill: parent; model: visualphotoModel.parts.browser; interactive: false }
|
||||
|
||||
Button {
|
||||
id: backButton
|
||||
text: qsTr("Back")
|
||||
x: parent.width - backButton.width - 3*mm
|
||||
y: -backButton.height - 4*mm
|
||||
onClicked: {photoBackground.opacity=0}
|
||||
// visible: Qt.platform.os !== "android"
|
||||
}
|
||||
|
||||
ListView {anchors.fill: parent; model: visualphotoModel.parts.fullscreen; interactive: false }
|
||||
WorkerScript{id: photoWorker;source: "qrc:/js/photoworker.js"}
|
||||
|
||||
function showOwnFotos(){
|
||||
try {photogroupModel.clear()}catch (e){print(e)}
|
||||
Helperjs.readField("album",root.db, "imageData",root.login.username,function(albums){
|
||||
if (albums[0]) {
|
||||
var msg = { 'model': photogroupModel,'albums':albums,'firstalbum':0,'foreignPicture': false};
|
||||
photoWorker.sendMessage(msg);
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
function onFriendsFotos(friend){print("Friend "+friend.url);
|
||||
try {photogroupModel.clear()}catch (e){print(e)}
|
||||
Service.requestFriendsAlbumPictures(friend,fotostab,function(albums){
|
||||
var msg = {'model': photogroupModel,'albums':albums,'firstalbum':0,'foreignPicture':true};
|
||||
photoWorker.sendMessage(msg);
|
||||
})
|
||||
}
|
||||
|
||||
Component.onCompleted: { root.fotoSignal.connect(onFriendsFotos);}
|
||||
}
|
119
v0.001/source-android/qml/PhotogroupComponent.qml
Normal file
119
v0.001/source-android/qml/PhotogroupComponent.qml
Normal file
|
@ -0,0 +1,119 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.LocalStorage 2.0
|
||||
import QtQuick.Controls 1.3
|
||||
import QtQml.Models 2.1
|
||||
import "qrc:/js/service.js" as Service
|
||||
import "qrc:/js/helper.js" as Helperjs
|
||||
|
||||
Package {
|
||||
Item {
|
||||
Package.name: 'browser'
|
||||
GridView {
|
||||
id: photosGridView; model: visualModel.parts.grid; width: albumgridview.width; height: albumgridview.height
|
||||
cellWidth: 16.5*mm; cellHeight: 16.5*mm; interactive: false;anchors.margins:2*mm
|
||||
onCurrentIndexChanged: photosListView.positionViewAtIndex(currentIndex, ListView.Contain)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Package.name: 'fullscreen'
|
||||
ListView {
|
||||
id: photosListView; model: visualModel.parts.list; orientation: Qt.Horizontal
|
||||
width: parent.width; height: parent.height; interactive: false
|
||||
onCurrentIndexChanged: photosGridView.positionViewAtIndex(currentIndex, GridView.Contain)
|
||||
highlightRangeMode: ListView.StrictlyEnforceRange; snapMode: ListView.SnapOneItem
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Package.name: 'album'
|
||||
id: albumWrapper; width: 16.5*mm; height: 16.5*mm //-albumtext.contentHeight
|
||||
|
||||
DelegateModel {
|
||||
id: visualModel; delegate: PhotoComponent { }
|
||||
model: photoModel
|
||||
}
|
||||
|
||||
PathView {
|
||||
id: photosPathView;
|
||||
model: visualModel.parts.stack;
|
||||
pathItemCount: 1
|
||||
anchors.centerIn: parent;
|
||||
path: Path {
|
||||
PathAttribute { name: 'z'; value: 9999.0 }
|
||||
PathLine { x: 1; y: 1 }
|
||||
PathAttribute { name: 'z'; value: 0.0 }
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle{
|
||||
color:"black"
|
||||
opacity: 0.5
|
||||
width:albumtext.contentWidth
|
||||
height: albumtext.contentHeight
|
||||
anchors.bottom: albumWrapper.bottom
|
||||
}
|
||||
Text {
|
||||
id:albumtext
|
||||
text: albumname //foreignPicture ? album.name.trim() : album
|
||||
width:albumWrapper.width-1*mm
|
||||
height: albumtext.contentHeight
|
||||
wrapMode:Text.Wrap
|
||||
color: "white"
|
||||
font.family: "Monospace"
|
||||
font.pixelSize: 2*mm
|
||||
anchors.bottom: albumWrapper.bottom
|
||||
}
|
||||
|
||||
ListModel{
|
||||
id: photoModel
|
||||
}
|
||||
|
||||
Component.onCompleted:{
|
||||
try {photoModel.clear()}catch (e){print(e)}
|
||||
if(foreignPicture){
|
||||
//print("Albumlink"+album.link);
|
||||
Service.requestFriendsPictures(albumlink,fotostab,function(obj){
|
||||
if (obj) {
|
||||
for (var k=0;k<obj.length;k++){
|
||||
//print("Photomodel:"+obj[k].thumb+obj[k].name+obj[k].link);
|
||||
photoModel.append({"imageLocation": obj[k].thumb,"photoDescription":obj[k].name,"photoLink":obj[k].link})
|
||||
};
|
||||
}
|
||||
})}
|
||||
else{
|
||||
Helperjs.readData(db,"imageData",function(obj){
|
||||
// obj.sort(function(obj1,obj2){return obj1.data-obj2.data});
|
||||
if (obj) {
|
||||
for (var k=0;k<obj.length;k++){
|
||||
// print("Photomodel:"+obj[k].location+obj[k].filename);
|
||||
photoModel.append({"imageLocation": obj[k].location+obj[k].filename,"photoDescription":obj[k].filename,"photoLink":obj[k].location+obj[k].filename})
|
||||
};
|
||||
}
|
||||
},"album",albumname)}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: albumWrapper.state = 'inGrid'
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: 'inGrid'
|
||||
PropertyChanges { target: photosGridView; interactive: true }
|
||||
PropertyChanges { target: photoBackground; opacity: 1 }
|
||||
PropertyChanges { target: backButton; onClicked: albumWrapper.state = ''; y: 6 }
|
||||
},
|
||||
State {
|
||||
name: 'fullscreen'; extend: 'inGrid'
|
||||
PropertyChanges { target: photosGridView; interactive: false }
|
||||
PropertyChanges { target: photosListView; interactive: true }
|
||||
PropertyChanges { target: photoBackground; opacity: 1 }
|
||||
PropertyChanges { target: backButton; y: -backButton.height - 8 }
|
||||
}
|
||||
]
|
||||
|
||||
} //album Ende
|
||||
} //Package Ende
|
||||
//item Ende
|
111
v0.001/source-android/qml/friendiqa.qml
Normal file
111
v0.001/source-android/qml/friendiqa.qml
Normal file
|
@ -0,0 +1,111 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.LocalStorage 2.0
|
||||
import QtQuick.Window 2.0
|
||||
import QtQuick.Dialogs 1.2
|
||||
import QtQuick.Controls 1.2
|
||||
|
||||
import QtQml.Models 2.1
|
||||
import "qrc:/js/news.js" as Newsjs
|
||||
import "qrc:/js/service.js" as Service
|
||||
import "qrc:/js/layout.js" as Layoutjs
|
||||
import "qrc:/js/helper.js" as Helperjs
|
||||
import "qrc:/qml"
|
||||
|
||||
|
||||
TabView{
|
||||
id:root
|
||||
tabPosition: Qt.BottomEdge
|
||||
width: Screen.desktopAvailableWidth
|
||||
height: Screen.desktopAvailableHeight
|
||||
|
||||
property var db: ["Photos", "1.0", "Stores Friendica data", 100000000]
|
||||
property var login: Service.readActiveConfig(db)
|
||||
property var contactlist: []
|
||||
property real mm: Screen.pixelDensity
|
||||
signal messageSignal(var friend)
|
||||
signal fotoSignal(var friend)
|
||||
signal directmessageSignal(var friend)
|
||||
signal newsSignal(var news)
|
||||
signal friendsSignal(var username)
|
||||
|
||||
currentIndex: (login=="")? 3:0
|
||||
|
||||
property var news:[]
|
||||
property var newContacts:[]
|
||||
property int currentContact: 0
|
||||
property string contactLoadType: ""
|
||||
|
||||
onLoginChanged:{Newsjs.newsfromdb( db,login.username, function(dbnews){
|
||||
newsSignal(dbnews)
|
||||
})}
|
||||
onNewContactsChanged:{if(newContacts.length>0){// download first contact image and update db
|
||||
//print("newcontact"+JSON.stringify(newContacts[0]));
|
||||
updateContactInDB(login,db,newContacts[currentContact].isFriend,newContacts[currentContact])}
|
||||
}
|
||||
onCurrentContactChanged:{// download next contact image after photoplaceholder is finished saving and update db
|
||||
if(currentContact<newContacts.length){
|
||||
updateContactInDB(login,db,newContacts[currentContact].isFriend,newContacts[currentContact])}
|
||||
else if(currentContact==newContacts.length){//newImagesProgress.visible=false;
|
||||
if (newContacts.length==0) {}
|
||||
else if (contactLoadType=="news"){
|
||||
Newsjs.storeNews(login,db,news,root,function(dbnews){
|
||||
root.newsSignal(dbnews);
|
||||
root.newContacts=[];
|
||||
root.currentContact=0;
|
||||
root.news=[]
|
||||
})// show news
|
||||
}
|
||||
else if (contactLoadType=="friends"){
|
||||
root.friendsSignal(login.username);
|
||||
// show friends
|
||||
Helperjs.readField("id",db,"contacts",login.username,function(contacts){contactlist=contacts;
|
||||
root.newContacts=[];
|
||||
root.currentContact=0},"isFriend",1) }
|
||||
}
|
||||
}
|
||||
|
||||
function updateContactInDB(login,database,isFriend,contact){// for newstab and friendstab
|
||||
var imagename=login.imagestore+contact.screen_name+".jpg";
|
||||
var component=Qt.createComponent("qrc:/qml/PhotoPlaceholder.qml");
|
||||
var sprite = component.createObject(root, {"fillMode": "Image.PreserveAspectFit","x":root.width,"y":50,"imageName":imagename,"source": contact.profile_image_url,"downloadtype":"contact"});
|
||||
var db=LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||
var result;
|
||||
db.transaction( function(tx) {
|
||||
result = tx.executeSql('SELECT * from contacts where id = '+contact.id); // check for news id
|
||||
if(result.rows.length === 1) {// use update
|
||||
result = tx.executeSql('UPDATE contacts SET username="'+login.username+'", id='+contact.id+', name="'+Qt.btoa(contact.name)+'", screen_name="'+contact.screen_name+'", location="'+contact.location+'",description="'+Qt.btoa(contact.description)+'", profile_image="'+imagename+'", url="'+contact.url+'" , protected="'+contact.protected+'", followers_count='+contact.followers_count+', friends_count='+contact.friends_count+', created_at="'+ Newsjs.cleanDate(contact.created_at)+'", favourites_count="'+contact.favorites_count+'", utc_offset="'+contact.utc_offset+'", time_zone="'+contact.time_zone+'", statuses_count='+contact.statuses_count+', following="'+contact.following+'", verified ="'+contact.verified+'", statusnet_blocking="'+contact.statusnet_blocking+'", notifications="'+contact.notifictions+'", statusnet_profile_url="'+contact.statusnet_profile_url+'", cid='+contact.cid+', network="'+contact.network+'", isFriend='+isFriend+' where id='+contact.id);
|
||||
} else {// use insert
|
||||
result = tx.executeSql('INSERT INTO contacts VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,contact.id,Qt.btoa(contact.name),contact.screen_name,contact.location,Qt.btoa(contact.description),imagename,contact.url,contact.protected,contact.followers_count, contact.friends_count,Newsjs.cleanDate(contact.created_at),contact.favorites_count,contact.utc_offset,contact.time_zone,contact.statuses_count,contact.following,contact.verfied,contact.statusnet_blocking,contact.notifications,contact.statusnet_profile_url,contact.cid,contact.network,isFriend]);}
|
||||
});
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (login==""){Service.initDatabase(db);
|
||||
}
|
||||
Helperjs.readField("id",db,"contacts",login.username,function(contacts){contactlist=contacts},"isFriend",1)
|
||||
}
|
||||
Tab{
|
||||
title: qsTr("News")
|
||||
id: newstab
|
||||
property string newstabStatus:"news"
|
||||
source: "qrc:/qml/NewsTab.qml"
|
||||
}
|
||||
|
||||
Tab{
|
||||
title: qsTr("Friends")
|
||||
id: friendstab
|
||||
source: "qrc:/qml/FriendsTab.qml"
|
||||
}
|
||||
Tab{
|
||||
title: qsTr("Photos")
|
||||
id: fotostab
|
||||
source: "qrc:/qml/PhotoTab.qml"
|
||||
}
|
||||
|
||||
|
||||
Tab{
|
||||
title: qsTr("Config")
|
||||
source: "qrc:/qml/ConfigTab.qml"
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue