version v0.6.7 with moderation

This commit is contained in:
LubuWest 2023-02-09 21:39:43 +01:00
commit 48a70b8395
46 changed files with 2106 additions and 1026 deletions

View file

@ -85,6 +85,10 @@ Rectangle {
return events
}
function createEvent(event){
rootstackView.push("qrc:/qml/calendarqml/EventCreate.qml",{"eventInformation": event})
}
BusyIndicator{
id: calBusy
anchors.horizontalCenter: calendarView.horizontalCenter
@ -150,7 +154,7 @@ Rectangle {
title: qsTr("Delete Event?")
standardButtons: Dialog.Ok | Dialog.Cancel
modal: true
onAccepted: {//print("event.id"+event.id);
onAccepted: {
xhr.setUrl(login.server);
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setApi("/api/friendica/event_delete");
@ -158,7 +162,7 @@ Rectangle {
xhr.setParam("id",eventid);
xhr.post();
}
onRejected: {print("eventid "+eventid);close()}
onRejected: {close()}
}
MButton{
@ -200,7 +204,6 @@ Rectangle {
width: 20*root.fontFactor*osSettings.systemFontSize
MenuItem {
text: qsTr("Own Calendar")
//font.pixelSize: 3*mm
font.pointSize: osSettings.systemFontSize
onTriggered: {
calendartab.calendartabstatus="Events";
@ -284,6 +287,7 @@ Rectangle {
}
Component.onCompleted: {
root.eventcreateSignal.connect(createEvent);
root.eventSignal.connect(showEvents);
if (calendartab.calendartabstatus=="Events"){showEvents("")}
}

View file

@ -38,354 +38,366 @@ import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/genericqml"
import "qrc:/qml/calendarqml"
Rectangle{
Flickable{
id:eventCreateBox
color: Material.backgroundColor
property date startDate: new Date()
property var eventInformation: ({})
anchors.fill: parent
contentWidth: eventRect.width; contentHeight: eventRect.height
function formatText(count, modelData) {
var data = count === 12 ? modelData + 1 : modelData;
return data.toString().length < 2 ? "0" + data : data;
}
MButton{
id:closeButton
anchors.top: parent.top
anchors.topMargin: 1*mm
anchors.right: parent.right
anchors.rightMargin: 1*mm
text: "\uf057"
onClicked:{rootstackView.pop()}
var data = count === 12 ? modelData + 1 : modelData;
return data.toString().length < 2 ? "0" + data : data;
}
Label{
x: 0.5*root.fontFactor*osSettings.bigFontSize
y: 2*root.fontFactor*osSettings.bigFontSize
width: 3*root.fontFactor*osSettings.bigFontSize
height: root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
//verticalAlignment: TextInput.AlignBottom
color: Material.primaryTextColor
text:qsTr("Start")
}
TextField {
id: textStartDate
property string dateDay:(startDate.getDate()).toString().length<2?"0"+(startDate.getDate()):(startDate.getDate())
property string dateMonth: (startDate.getMonth()+1).toString().length<2?"0"+(startDate.getMonth()+1):(startDate.getMonth()+1)
x: 4*root.fontFactor*osSettings.bigFontSize
y: root.fontFactor*osSettings.bigFontSize
width: 5*root.fontFactor*osSettings.bigFontSize
height: 2.5*root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
horizontalAlignment: TextInput.AlignRight
text: dateDay+"-"+dateMonth+"-"+startDate.getFullYear()
inputMask: "99-99-9999"
validator: RegExpValidator{regExp: /^([0-2\s]?[0-9\s]|3[0-1\s])-(0[0-9\s]|1[0-2\s])-([0-9\s][0-9\s][0-9\s][0-9\s])$ / }
font.bold: true
}
MButton {
id: textStartDateDropdown
x: 9.5*root.fontFactor*osSettings.bigFontSize
y: root.fontFactor*osSettings.bigFontSize
width: 2*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
text:"\uf0d7"
onClicked:{
cal.visible=true;
cal.curSelection="start"
}
}
TextField {
id: textStartTime
x: 13*root.fontFactor*osSettings.bigFontSize
y: root.fontFactor*osSettings.bigFontSize
width: 3*root.fontFactor*osSettings.bigFontSize
height: 2.5*root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
inputMask: "99:99"
text: "00:00"
horizontalAlignment: TextInput.AlignRight
validator: RegExpValidator{regExp: /^([0-1\s]?[0-9\s]|2[0-3\s]):([0-5\s][0-9\s])$ / }
font.bold: true
}
MButton {
id: textStartTimeDropdown
x: 16.5*root.fontFactor*osSettings.bigFontSize
y: root.fontFactor*osSettings.bigFontSize
width: 2*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
text:"\uf0d7"
onClicked:{
onClicked: {timeTumbler.visible=true;timeTumbler.curSelection="start"}
}
}
Label{
x: 0.5*root.fontFactor*osSettings.bigFontSize
y: 4*root.fontFactor*osSettings.bigFontSize
width: 3*root.fontFactor*osSettings.bigFontSize
height: root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
color: Material.primaryTextColor
text:qsTr("End")
}
TextField {
id: textEndDate
x: 4*root.fontFactor*osSettings.bigFontSize
y: 3*root.fontFactor*osSettings.bigFontSize
width: 5*root.fontFactor*osSettings.bigFontSize
height: 2.5*root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
horizontalAlignment: TextInput.AlignRight
inputMask: "99-99-9999"
validator: RegExpValidator{regExp: /^([0-2\s]?[0-9\s]|3[0-1\s])-(0[0-9\s]|1[0-2\s])-([0-9\s][0-9\s][0-9\s][0-9\s])$ / }
enabled: false
font.bold: true
}
MButton {
id: textEndDateDropdown
x: 9.5*root.fontFactor*osSettings.bigFontSize
y: 3*root.fontFactor*osSettings.bigFontSize
width: 2*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
enabled: false
text:"\uf0d7"
onClicked:{
cal.visible=true;
cal.curSelection="end"
}
}
TextField {
id: textEndTime
x: 13*root.fontFactor*osSettings.bigFontSize
y: 3*root.fontFactor*osSettings.bigFontSize
width: 3*root.fontFactor*osSettings.bigFontSize
height: 2.5*root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
enabled: false
horizontalAlignment: TextInput.AlignRight
inputMask: "99:99"
validator: RegExpValidator{regExp: /^([0-1\s]?[0-9\s]|2[0-3\s]):([0-5\s][0-9\s])$ / }
font.bold: true
}
MButton {
id: textEndTimeDropdown
x: 16.5*root.fontFactor*osSettings.bigFontSize
y: 3*root.fontFactor*osSettings.bigFontSize
width: 2*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
enabled: false
text:"\uf0d7"
onClicked:{
onClicked: {timeTumbler.visible=true;timeTumbler.curSelection="end"}
}
}
Column{
x: 4*root.fontFactor*osSettings.bigFontSize
y: 6*root.fontFactor*osSettings.bigFontSize
width: parent.width-7*root.fontFactor*osSettings.bigFontSize
Oldcontrols.Calendar{
id:cal
property string curSelection: "start"
width: 12*root.fontFactor*osSettings.bigFontSize
height: 15*root.fontFactor*osSettings.bigFontSize
visible: false
selectedDate: new Date()
onClicked: {
if (curSelection=="start"){
textStartDate.text=Qt.formatDate(cal.selectedDate, "dd-MM-yyyy");
}else{
textEndDate.text=Qt.formatDate(cal.selectedDate, "dd-MM-yyyy");
}
cal.visible=false
}
}
Frame {
id: timeTumbler
width: 12*root.fontFactor*osSettings.bigFontSize
height: 10*root.fontFactor*osSettings.bigFontSize
visible: false
property string curSelection: "start"
Row {
Tumbler {
id: hoursTumbler
model: 24
delegate: tumblerDelegateComponent
currentIndex: 12
}
Tumbler {
id: minutesTumbler
model: 60
delegate: tumblerDelegateComponent
}
}
MButton {
id: timeInputfinished
width: 2*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
text:"\uf00c"
onClicked:{
if (timeTumbler.curSelection=="start"){
textStartTime.text=formatText(24,hoursTumbler.currentIndex)+":"+formatText(60,minutesTumbler.currentIndex);
}else{
textEndTime.text=formatText(24,hoursTumbler.currentIndex)+":"+formatText(60,minutesTumbler.currentIndex);
}
timeTumbler.visible=false
}
}
}
CheckBox{
id: checkNoEndTime
width: 12*root.fontFactor*osSettings.bigFontSize
height: 2.5*root.fontFactor*osSettings.bigFontSize
checked: true
font.pointSize: osSettings.systemFontSize
text: qsTr("no end")
onCheckedChanged: {
if(checked==true){
textEndDate.enabled=false;
textEndDateDropdown.enabled=false;
textEndTime.enabled=false;
textEndTimeDropdown.enabled=false;
textEndDate.text="";
textEndTime.text=""
}else{
textEndDate.enabled=true;
textEndDateDropdown.enabled=true;
textEndTime.enabled=true;
textEndTimeDropdown.enabled=true;
textEndDate.text=textStartDate.text;
textEndTime.text=textStartTime.text
}
}
}
TextField {
id: titleField
width: parent.width-root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
font.bold: true
placeholderText: qsTr("Title (required)")
}
Rectangle{
color: Material.backgroundColor
radius: 0.5*mm
width: parent.width-root.fontFactor*osSettings.bigFontSize
height:Math.max(bodyField.contentHeight+root.fontFactor*osSettings.bigFontSize,2.5*root.fontFactor*osSettings.bigFontSize)
TextArea {
id: bodyField
anchors.fill: parent
font.pointSize: osSettings.systemFontSize
font.family: "Noto Sans"
wrapMode: Text.Wrap
selectByMouse: true
placeholderText: qsTr("Event description (optional)")
textFormat: TextEdit.PlainText
onLinkActivated:{Qt.openUrlExternally(link)}
}
}
TextField {
id: locationField
width: parent.width-root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
placeholderText: qsTr("Location (optional)")
}
CheckBox{
id: chkbxPublish
width: 10*root.fontFactor*osSettings.bigFontSize
height: 2.5*root.fontFactor*osSettings.bigFontSize
checked: true
font.pointSize: osSettings.systemFontSize
text: qsTr("Publish event?")
}
BusyIndicator{
id: eventCreateBusy
anchors.horizontalCenter: eventCreateBox.horizontalCenter
anchors.top:eventCreateBox.top
anchors.topMargin: 2*root.fontFactor*osSettings.bigFontSize
width:3*root.fontFactor*osSettings.bigFontSize
height: 3*root.fontFactor*osSettings.bigFontSize
running: false
}
boundsBehavior:Flickable.StopAtBounds
ScrollBar.vertical: ScrollBar { }
Rectangle{
id: eventRect
width: root.width
height: textColumn.height + 6*root.fontFactor*osSettings.bigFontSize
color: Material.backgroundColor
MButton{
id:createEventButton
text: qsTr("Create event")
onClicked:{
let startdatetext=textStartDate.getText(0,textStartDate.length);
let startdate=new Date(startdatetext.substring(6,10)+"-"+startdatetext.substring(3,5)+"-"+startdatetext.substring(0,2)+"T"+textStartTime.text)
id:closeButton
anchors.top: parent.top
anchors.topMargin: 1*mm
anchors.right: parent.right
anchors.rightMargin: 1*mm
text: "\uf057"
onClicked:{rootstackView.pop()}
}
if (titleField.text==""){
Helperjs.showMessage(qsTr("Error"),qsTr("No event name supplied"),eventCreateBox)
}else{
Label{
x: 0.5*root.fontFactor*osSettings.bigFontSize
y: 2*root.fontFactor*osSettings.bigFontSize
width: 3*root.fontFactor*osSettings.bigFontSize
height: root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
//verticalAlignment: TextInput.AlignBottom
color: Material.primaryTextColor
text:qsTr("Start")
}
TextField {
id: textStartDate
property string dateDay:(startDate.getDate()).toString().length<2?"0"+(startDate.getDate()):(startDate.getDate())
property string dateMonth: (startDate.getMonth()+1).toString().length<2?"0"+(startDate.getMonth()+1):(startDate.getMonth()+1)
x: 4*root.fontFactor*osSettings.bigFontSize
y: root.fontFactor*osSettings.bigFontSize
width: 5*root.fontFactor*osSettings.bigFontSize
height: 2.5*root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
horizontalAlignment: TextInput.AlignRight
text: dateDay+"-"+dateMonth+"-"+startDate.getFullYear()
inputMask: "99-99-9999"
validator: RegExpValidator{regExp: /^([0-2\s]?[0-9\s]|3[0-1\s])-(0[0-9\s]|1[0-2\s])-([0-9\s][0-9\s][0-9\s][0-9\s])$ / }
font.bold: true
}
MButton {
id: textStartDateDropdown
x: 9.5*root.fontFactor*osSettings.bigFontSize
y: root.fontFactor*osSettings.bigFontSize
width: 2*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
text:"\uf0d7"
onClicked:{
cal.visible=true;
cal.curSelection="start"
}
}
TextField {
id: textStartTime
x: 13*root.fontFactor*osSettings.bigFontSize
y: root.fontFactor*osSettings.bigFontSize
width: 3*root.fontFactor*osSettings.bigFontSize
height: 2.5*root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
inputMask: "99:99"
text: "00:00"
horizontalAlignment: TextInput.AlignRight
validator: RegExpValidator{regExp: /^([0-1\s]?[0-9\s]|2[0-3\s]):([0-5\s][0-9\s])$ / }
font.bold: true
}
MButton {
id: textStartTimeDropdown
x: 16.5*root.fontFactor*osSettings.bigFontSize
y: root.fontFactor*osSettings.bigFontSize
width: 2*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
text:"\uf0d7"
onClicked:{
onClicked: {timeTumbler.visible=true;timeTumbler.curSelection="start"}
}
}
Label{
x: 0.5*root.fontFactor*osSettings.bigFontSize
y: 4*root.fontFactor*osSettings.bigFontSize
width: 3*root.fontFactor*osSettings.bigFontSize
height: root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
color: Material.primaryTextColor
text:qsTr("End")
}
TextField {
id: textEndDate
x: 4*root.fontFactor*osSettings.bigFontSize
y: 3*root.fontFactor*osSettings.bigFontSize
width: 5*root.fontFactor*osSettings.bigFontSize
height: 2.5*root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
horizontalAlignment: TextInput.AlignRight
inputMask: "99-99-9999"
validator: RegExpValidator{regExp: /^([0-2\s]?[0-9\s]|3[0-1\s])-(0[0-9\s]|1[0-2\s])-([0-9\s][0-9\s][0-9\s][0-9\s])$ / }
enabled: false
font.bold: true
}
MButton {
id: textEndDateDropdown
x: 9.5*root.fontFactor*osSettings.bigFontSize
y: 3*root.fontFactor*osSettings.bigFontSize
width: 2*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
enabled: false
text:"\uf0d7"
onClicked:{
cal.visible=true;
cal.curSelection="end"
}
}
TextField {
id: textEndTime
x: 13*root.fontFactor*osSettings.bigFontSize
y: 3*root.fontFactor*osSettings.bigFontSize
width: 3*root.fontFactor*osSettings.bigFontSize
height: 2.5*root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
enabled: false
horizontalAlignment: TextInput.AlignRight
inputMask: "99:99"
validator: RegExpValidator{regExp: /^([0-1\s]?[0-9\s]|2[0-3\s]):([0-5\s][0-9\s])$ / }
font.bold: true
}
MButton {
id: textEndTimeDropdown
x: 16.5*root.fontFactor*osSettings.bigFontSize
y: 3*root.fontFactor*osSettings.bigFontSize
width: 2*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
enabled: false
text:"\uf0d7"
onClicked:{
onClicked: {timeTumbler.visible=true;timeTumbler.curSelection="end"}
}
}
Column{
id: textColumn
x: 4*root.fontFactor*osSettings.bigFontSize
y: 6*root.fontFactor*osSettings.bigFontSize
width: parent.width-7*root.fontFactor*osSettings.bigFontSize
Oldcontrols.Calendar{
id:cal
property string curSelection: "start"
width: 12*root.fontFactor*osSettings.bigFontSize
height: 15*root.fontFactor*osSettings.bigFontSize
visible: false
selectedDate: new Date()
onClicked: {
if (curSelection=="start"){
textStartDate.text=Qt.formatDate(cal.selectedDate, "dd-MM-yyyy");
}else{
textEndDate.text=Qt.formatDate(cal.selectedDate, "dd-MM-yyyy");
}
cal.visible=false
}
}
Frame {
id: timeTumbler
width: 12*root.fontFactor*osSettings.bigFontSize
height: 10*root.fontFactor*osSettings.bigFontSize
visible: false
property string curSelection: "start"
Row {
Tumbler {
id: hoursTumbler
model: 24
delegate: tumblerDelegateComponent
currentIndex: 12
}
Tumbler {
id: minutesTumbler
model: 60
delegate: tumblerDelegateComponent
}
}
MButton {
id: timeInputfinished
width: 2*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
text:"\uf00c"
onClicked:{
if (timeTumbler.curSelection=="start"){
textStartTime.text=formatText(24,hoursTumbler.currentIndex)+":"+formatText(60,minutesTumbler.currentIndex);
}else{
textEndTime.text=formatText(24,hoursTumbler.currentIndex)+":"+formatText(60,minutesTumbler.currentIndex);
}
timeTumbler.visible=false
}
}
}
CheckBox{
id: checkNoEndTime
width: 12*root.fontFactor*osSettings.bigFontSize
height: 2.5*root.fontFactor*osSettings.bigFontSize
checked: true
font.pointSize: osSettings.systemFontSize
text: qsTr("no end")
onCheckedChanged: {
if(checked==true){
textEndDate.enabled=false;
textEndDateDropdown.enabled=false;
textEndTime.enabled=false;
textEndTimeDropdown.enabled=false;
textEndDate.text="";
textEndTime.text=""
}else{
textEndDate.enabled=true;
textEndDateDropdown.enabled=true;
textEndTime.enabled=true;
textEndTimeDropdown.enabled=true;
textEndDate.text=textStartDate.text;
textEndTime.text=textStartTime.text
}
}
}
TextField {
id: titleField
width: parent.width-root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
font.bold: true
placeholderText: qsTr("Title (required)")
}
Rectangle{
color: Material.backgroundColor
radius: 0.5*mm
width: parent.width-root.fontFactor*osSettings.bigFontSize
height:Math.max(bodyField.contentHeight+root.fontFactor*osSettings.bigFontSize,2.5*root.fontFactor*osSettings.bigFontSize)
TextArea {
id: bodyField
anchors.fill: parent
font.pointSize: osSettings.systemFontSize
font.family: "Noto Sans"
wrapMode: Text.Wrap
selectByMouse: true
placeholderText: qsTr("Event description (optional)")
textFormat: TextEdit.PlainText
text: eventInformation.hasOwnProperty("text")?eventInformation.text:""
onLinkActivated:{Qt.openUrlExternally(link)}
}
}
TextField {
id: locationField
width: parent.width-root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
placeholderText: qsTr("Location (optional)")
}
CheckBox{
id: chkbxPublish
width: 10*root.fontFactor*osSettings.bigFontSize
height: 2.5*root.fontFactor*osSettings.bigFontSize
checked: true
font.pointSize: osSettings.systemFontSize
text: qsTr("Publish event?")
}
BusyIndicator{
id: eventCreateBusy
anchors.horizontalCenter: eventCreateBox.horizontalCenter
anchors.top:eventCreateBox.top
anchors.topMargin: 2*root.fontFactor*osSettings.bigFontSize
width:3*root.fontFactor*osSettings.bigFontSize
height: 3*root.fontFactor*osSettings.bigFontSize
running: false
}
MButton{
id:createEventButton
text: qsTr("Create event")
onClicked:{
let startdatetext=textStartDate.getText(0,textStartDate.length);
let startdate=new Date(startdatetext.substring(6,10)+"-"+startdatetext.substring(3,5)+"-"+startdatetext.substring(0,2)+"T"+textStartTime.text)
eventCreateBusy.running=true;
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setUrl(login.server);
xhr.setApi("/api/friendica/event_create");
xhr.clearParams();
xhr.setParam("name", titleField.text);
xhr.setParam("start_time",startdate.toISOString())
if(!checkNoEndTime.checked){
let enddatetext=textEndDate.getText(0,textEndDate.length);
let enddate=new Date(enddatetext.substring(6,10)+"-"+enddatetext.substring(3,5)+"-"+enddatetext.substring(0,2)+"T"+textEndTime.text)
xhr.setParam("end_time",enddate.toISOString())
}
xhr.setParam("name",titleField.text)
if (bodyField.text!=""){xhr.setParam("desc",bodyField.text)}
if (locationField.text!=""){xhr.setParam("place",locationField.text)}
xhr.setParam("publish",chkbxPublish.checked)
xhr.post();
}
}
}
Connections{
target: xhr
function onSuccess(text,api){
if (api=="/api/friendica/event_create"){
updatenews.setDatabase();
updatenews.login();
updatenews.setSyncAll(false);
updatenews.events();
try{while(rootstackView.depth>1){rootstackView.pop()}}catch(e){}
}
}
function onError(text,api){
if (api=="/api/friendica/event_create"){
Helperjs.showMessage(qsTr("Error"),text,root)
}
}
}
}
Component {
id: tumblerDelegateComponent
Label {
text: formatText(Tumbler.tumbler.count, modelData)
opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2)
color:Material.primaryTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pointSize: osSettings.systemFontSize
if (titleField.text==""){
Helperjs.showMessage(qsTr("Error"),qsTr("No event name supplied"),eventCreateBox)
}else{
let startdatetext=textStartDate.getText(0,textStartDate.length);
let startdate=new Date(startdatetext.substring(6,10)+"-"+startdatetext.substring(3,5)+"-"+startdatetext.substring(0,2)+"T"+textStartTime.text)
eventCreateBusy.running=true;
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setUrl(login.server);
xhr.setApi("/api/friendica/event_create");
xhr.clearParams();
xhr.setParam("name", titleField.text);
xhr.setParam("start_time",startdate.toISOString())
if(!checkNoEndTime.checked){
let enddatetext=textEndDate.getText(0,textEndDate.length);
let enddate=new Date(enddatetext.substring(6,10)+"-"+enddatetext.substring(3,5)+"-"+enddatetext.substring(0,2)+"T"+textEndTime.text)
xhr.setParam("end_time",enddate.toISOString())
}
xhr.setParam("name",titleField.text)
if (bodyField.text!=""){xhr.setParam("desc",bodyField.text)}
if (locationField.text!=""){xhr.setParam("place",locationField.text)}
xhr.setParam("publish",chkbxPublish.checked)
xhr.post();
}
}
}
Connections{
target: xhr
function onSuccess(text,api){
if (api=="/api/friendica/event_create"){
updatenews.setDatabase();
updatenews.login();
updatenews.setSyncAll(false);
updatenews.events();
try{while(rootstackView.depth>1){rootstackView.pop()}}catch(e){}
}
}
function onError(text,api){
if (api=="/api/friendica/event_create"){
Helperjs.showMessage(qsTr("Error"),text,root)
}
}
}
}
Component {
id: tumblerDelegateComponent
Label {
text: formatText(Tumbler.tumbler.count, modelData)
opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2)
color:Material.primaryTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pointSize: osSettings.systemFontSize
}
}
}
}

View file

@ -73,7 +73,7 @@ Rectangle{
title: qsTr("Delete Event?")
standardButtons: Dialog.Ok | Dialog.Cancel
modal: true
onAccepted: {//print("event.id"+event.id);
onAccepted: {
xhr.setUrl(login.server);
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setApi("/api/friendica/event_delete");
@ -81,7 +81,7 @@ Rectangle{
xhr.setParam("id",eventid);
xhr.post();
}
onRejected: {print("eventid "+eventid);close()}
onRejected: {close()}
}
ListView {

View file

@ -99,7 +99,7 @@ Rectangle{
}
}
onClicked:{print("status "+status)
onClicked:{
if (status==""){
rootstackView.push("qrc:/qml/calendarqml/EventList.qml",{"dayint": event.startday, "events":[event]});
} else {rootstackView.pop()}

View file

@ -0,0 +1,70 @@
// This file is part of Friendiqa
// https://git.friendi.ca/lubuwest/Friendiqa
// Copyright (C) 2020 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0
import QtQuick.Controls 2.15
import QtQuick.Controls.Material 2.12
Dialog {
id: rulesDialog
height: parent.height/2
width: parent.width
anchors.centerIn: parent
title: qsTr("Accept instance rules")
property string rules: ""
standardButtons: Dialog.Yes | Dialog.No
modal: true
onAccepted: {
username.visible=true;
password.visible=true;
ruleButton.visible=false;
confirmation.visible=true
}
onRejected: {close()}
ScrollView{
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
width: root.width-2*root.fontFactor*osSettings.bigFontSize
height:parent.height
clip:true
Text {
x:1; y:1
width: root.width-4*root.fontFactor*osSettings.bigFontSize
wrapMode: TextEdit.Wrap
color: Material.primaryTextColor
linkColor: Material.accentColor
textFormat: Text.PlainText
font.family: "Noto Sans"
font.pointSize: osSettings.systemFontSize
text: rules
}
}
}

View file

@ -74,6 +74,7 @@ Page{
useritems=useritems+"MenuItem{font.pointSize: osSettings.bigFontSize;width:accountPage.width*2/3; text:'"+accountPage.users[i].username+
"'; onTriggered: {Service.readConfig(db,function(obj){
userButton.text=obj.username;
servername.text=obj.server;
serverModel.insert(0,{text:obj.server})
accountPage.setServericon(obj.server);
username.text= obj.username;
@ -148,7 +149,7 @@ Page{
x: 4*root.fontFactor*osSettings.bigFontSize
y: 3.5*root.fontFactor*osSettings.bigFontSize
width: root.width-5*root.fontFactor*osSettings.bigFontSize
height: 2.5*root.fontFactor*osSettings.bigFontSize//5*mm;
height: 2.5*root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
text:"https://"
onFocusChanged:{
@ -199,10 +200,32 @@ Page{
ListElement{text:"https://venera.social"}
}
MButton {
id: ruleButton
x: root.fontFactor*osSettings.bigFontSize; y: 6*root.fontFactor*osSettings.bigFontSize; width: root.width-9*mm;
visible: (osSettings.osType=="Android") && (userButton.text== qsTr("User"))
height: 2*root.fontFactor*osSettings.bigFontSize;
text: qsTr("Instance rules")
font.pointSize: osSettings.bigFontSize
onClicked:{
Helperjs.friendicaWebRequest(servername.text+"/api/v1/instance/rules",root,function(rules){
let rulestext="";
let rulesarray=JSON.parse(rules)
for (let rule in rulesarray){
rulestext=rulestext+rulesarray[rule].text+"\n"
}
var component = Qt.createComponent("qrc:/qml/configqml/AcceptRules.qml");
var rulesdialog = component.createObject(root,{"rules": rulestext});
rulesdialog.open()
})
}
}
TextField {
id: username
x: root.fontFactor*osSettings.bigFontSize; y: 6*root.fontFactor*osSettings.bigFontSize; width: root.width-9*mm; //height: 5*mm;
font.pointSize: osSettings.systemFontSize
visible: (osSettings.osType=="Android")?(userButton.text!= qsTr("User")):true
placeholderText: qsTr("Nickname")
selectByMouse: true
onEditingFinished: {
@ -219,6 +242,7 @@ Page{
id: password
x: root.fontFactor*osSettings.bigFontSize; y: 9*root.fontFactor*osSettings.bigFontSize; width: root.width-9*mm; //height: 5*mm;
font.pointSize: osSettings.systemFontSize
visible: (osSettings.osType=="Android")?(userButton.text!= qsTr("User")):true
selectByMouse: true
echoMode: TextInput.Password
placeholderText: qsTr("Password")
@ -243,6 +267,7 @@ Page{
wrapMode: TextEdit.NoWrap
onTextChanged: imagestoredir=imagestore.text
}
MButton {
x: root.width-3*root.fontFactor*osSettings.bigFontSize; y: 13*root.fontFactor*osSettings.bigFontSize;
height: 2*root.fontFactor*osSettings.bigFontSize;
@ -252,7 +277,6 @@ Page{
onClicked:{imagestoreDialog.open()}
}
FileDialog {
id: imagestoreDialog
title: "Please choose a directory"
@ -265,7 +289,6 @@ Page{
}
}
BusyIndicator{
id: accountBusy
anchors.horizontalCenter: parent.horizontalCenter
@ -276,56 +299,56 @@ Page{
}
MButton {
x: root.fontFactor*osSettings.bigFontSize; y: 16*root.fontFactor*osSettings.bigFontSize
text: qsTr("Confirm")
font.pointSize: osSettings.bigFontSize
onClicked:{
accountBusy.running=true;//servername.displayText
var userconfig={server: servername.displayText, username: username.text, password:Qt.btoa(password.text), imagestore:imagestoredir,interval: ""};
var errormessage="";
if (servername.text==""){errormessage=qsTr("No server given! ")}
else if (username.text==""){errormessage+=qsTr("No nickname given! ")}
else if (password.text=="") {errormessage+=qsTr("No password given! ")}
else if (imagestoredir=="") {errormessage+=qsTr("No image directory given!")}
id:confirmation
x: root.fontFactor*osSettings.bigFontSize; y: 16*root.fontFactor*osSettings.bigFontSize
text: qsTr("Confirm")
font.pointSize: osSettings.bigFontSize
visible: (osSettings.osType=="Android")?userButton.text!= qsTr("User"):true
onClicked:{
accountBusy.running=true;//servername.displayText
var userconfig={server: servername.displayText, username: username.text, password:Qt.btoa(password.text), imagestore:imagestoredir,interval: ""};
var errormessage="";
if (servername.text==""){errormessage=qsTr("No server given! ")}
else if (username.text==""){errormessage+=qsTr("No nickname given! ")}
else if (password.text=="") {errormessage+=qsTr("No password given! ")}
else if (imagestoredir=="") {errormessage+=qsTr("No image directory given!")}
else {errormessage=""}
if (errormessage=="") {
Helperjs.friendicaRequest(userconfig,"/api/account/verify_credentials.json?skip_status=true",root,function(obj){
accountBusy.running=false;
try{var credentials=JSON.parse(obj);
if (credentials.hasOwnProperty('error')){
Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root)
}
else{
if (users.length==0){Service.setDefaultOptions(db);}
if(userconfig.imagestore == filesystem.homePath+"/"+username.text+"/")
{
filesystem.makePath(filesystem.homePath+"/"+username.text);
}
filesystem.Directory=imagestoredir //userconfig.imagestore;
filesystem.makeDir("contacts");
filesystem.makeDir("albums");
userconfig.accountId=credentials.id
Service.storeConfig(db,userconfig);
Service.readConfig(db,function(userconfig){
Helperjs.readData(db,"config","",function(storedUsers){
storedUsers.sort(function(obj1, obj2) {
return obj1.isActive - obj2.isActive;
});
accountPage.users=storedUsers});
//reset values
login=userconfig;
news=[];
contactlist=[];
rootstack.currentIndex=0;
newstypeSignal("refresh");
},"isActive",0);
//Service.requestProfile(userconfig,db,root,function(nc){root.newContacts=nc});
Helperjs.showMessage(qsTr("Success"),qsTr("Name")+": "+credentials.name+"\nScreen Name: "+credentials.screen_name,root)
rootstackView.pop()
}
}catch(e){Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password!"),root)};
else {errormessage=""}
if (errormessage=="") {
Helperjs.friendicaRequest(userconfig,"/api/account/verify_credentials.json?skip_status=true",root,function(obj){
accountBusy.running=false;
try{var credentials=JSON.parse(obj);
if (credentials.hasOwnProperty('error')){
Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password or 2FA enabled!"),root)
}
else{
if (users.length==0){Service.setDefaultOptions(db);}
if(userconfig.imagestore == filesystem.homePath+"/"+username.text+"/")
{
filesystem.makePath(filesystem.homePath+"/"+username.text);
}
filesystem.Directory=imagestoredir
filesystem.makeDir("contacts");
filesystem.makeDir("albums");
userconfig.accountId=credentials.id
Service.storeConfig(db,userconfig);
Service.readConfig(db,function(userconfig){
Helperjs.readData(db,"config","",function(storedUsers){
storedUsers.sort(function(obj1, obj2) {
return obj1.isActive - obj2.isActive;
});
accountPage.users=storedUsers});
//reset values
login=userconfig;
news=[];
contactlist=[];
rootstack.currentIndex=0;
newstypeSignal("refresh");
},"isActive",0);
Helperjs.showMessage(qsTr("Success"),qsTr("Name")+": "+credentials.name+"\nScreen Name: "+credentials.screen_name,root)
rootstackView.pop()
}
}catch(e){Helperjs.showMessage(qsTr("Error"),qsTr("Wrong password or 2FA enabled!"),root)};
})}
else {Helperjs.showMessage(qsTr("Error"), errormessage,root)}
@ -379,7 +402,7 @@ Page{
servericon.source="";
username.text=""
password.text=""
imagestore.text="" //filesystem.homePath+"/.friendiqa/"+username.text//""
imagestore.text=""
userButton.text=qsTr("User")
}
}

View file

@ -43,7 +43,7 @@ Page{
font.pointSize: osSettings.systemFontSize
color:Material.primaryTextColor
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
text: "<b>Friendiqa v0.6.6 </b><br>Licensed under GPL 3 with the exception of OpenSSL <br> "+
text: "<b>Friendiqa v0.6.7 </b><br>Licensed under GPL 3 with the exception of OpenSSL <br> "+
"Website <a href='https://friendiqa.ma-nic.de'>https://friendiqa.ma-nic.de</a><br>"+
"Sourcecode: <a href='https://git.friendi.ca/LubuWest/Friendiqa'>https://git.friendi.ca/LubuWest/Friendiqa</a><br>"+
"Privacy Policy: <a href='https://git.friendi.ca/lubuwest/Friendiqa/src/branch/master/PrivacyPolicy.md'>http://git.friendi.ca/lubuwest/Friendiqa/src/branch/master/PrivacyPolicy.md</a><br>"+

View file

@ -44,6 +44,7 @@ Item{
Layout.fillWidth:true
Layout.fillHeight: true
property int currentContact: 0
signal contactRefreshSignal()
function showFriends(username){
try {friendsModel.clear()} catch(e){};
@ -86,6 +87,19 @@ Item{
},searchText.text,-1);
}
function showBlocked(contact){
try {friendsModel.clear()} catch(e){};
Newsjs.listBlocked(login,db,function(contactsobject){
for (var j=0;j<contactsobject.length;j++){
contactsobject[j].description=Qt.atob(contactsobject[j].description);
if(Helperjs.getCount(db,login,"contacts","screen_name",contactsobject[j].screen_name)>1){
contactsobject[j].screen_name=contactsobject[j].screen_name+"+"+contactsobject[j].cid
}
friendsModel.append({"contact":contactsobject[j]});
}
});
}
Connections{
target:xhr
function onDownloaded(type,url,filename,i){
@ -159,14 +173,18 @@ Item{
width: 6*root.fontFactor*osSettings.bigFontSize
height: 1.5*root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
model: [qsTr("Friends"), qsTr("All")]
model: [qsTr("Friends"), qsTr("All"), qsTr("Blocked")]
onCurrentIndexChanged:{
if (currentIndex === 0) {
showFriends(root.login.username);
} else{
} else
if (currentIndex===1){
showContacts()
} else if (currentIndex===2){
showBlocked()
}
}
Component.onCompleted: {root.contactRefreshSignal.connect(onCurrentIndexChanged)}
}

View file

@ -51,9 +51,6 @@ Item{
function updateGroup(login,database,group){
// update groups
//var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
//var groupdata={"gid":group.id,"name":group.name,"user":group.user};
//print("Groupdata "+JSON.stringify(group));
var api="";
if (group.new){api="/api/friendica/group_create.json?name="+group.name}else{api="/api/friendica/group_update.json?gid="+group.id}
xhr.setUrl(login.server);

View file

@ -61,8 +61,10 @@ ApplicationWindow{
signal newstypeSignal(var type)
signal friendsSignal(var username)
signal contactdetailsSignal(var contact)
signal contactRefreshSignal()
signal searchSignal (var searchterm)
signal eventSignal(var contact)
signal eventcreateSignal(var event)
signal uploadSignal(var urls)
signal sendtextSignal(var intenttext)
signal changeimage(var method, var type, var id)
@ -202,7 +204,10 @@ ApplicationWindow{
TabBar {
id: bar
Layout.fillWidth: true
onCurrentIndexChanged: rootstack.currentIndex=bar.currentIndex
onCurrentIndexChanged: {
rootstack.currentIndex=bar.currentIndex;
try{while(rootstackView.depth>1){rootstackView.pop()}}catch(e){}
}
TabButton {
text: "\uf03a"
background:Rectangle{

View file

@ -42,12 +42,13 @@ Rectangle{
radius: mm
property alias text: mainText.text
property alias font: mainText.font
property alias fontSize: mainText.font.pointSize
signal clicked
state:""
Text{
id:mainText
color: "black"
color: Material.primaryTextColor//"black"
anchors.centerIn: parent
width: contentWidth
height: contentHeight

View file

@ -63,10 +63,10 @@ Item {
onClicked: {
login=account;
if(!wideScreen){leftDrawerAndroid.close()}
newstypeSignal("refresh")
// updatenews.setDatabase();
// updatenews.login();
// updatenews.startsync();
// newstypeSignal("refresh")
updatenews.setDatabase();
updatenews.login();
updatenews.startsync();
}
}
}

View file

@ -29,161 +29,180 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls.Material 2.12
import Qt.labs.folderlistmodel 2.1
import QtQuick.Dialogs 1.2
import Qt.labs.folderlistmodel 2.12
import "qrc:/js/service.js" as Service
import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/genericqml"
Rectangle{
Item{
id:imageDialog
z:2
border.color: "grey"
color: Material.backgroundColor
width: parent.width-4*mm
height:parent.height-12*mm
x:2*mm
y:10*mm
// border.color: "grey"
// color: Material.backgroundColor
// width: parent.width-root.fontFactor*osSettings.bigFontSize
// height: parent.height-3*root.fontFactor*osSettings.bigFontSize
// x: 0.5*root.fontFactor*osSettings.bigFontSize
// y: 2*root.fontFactor*osSettings.bigFontSize
property string directory: ""
property bool multiple: false
property string imageUrl: ""
property var imageUrls: []
//property var imageUrls: []
signal ready();
function pickImage() {}
function pickImage() {imageFileDialog.open()}
Text{
id:directoryText
x:0.5*mm
y:0.5*mm
width: imageDialog.width-15*mm
height:contentHeight
wrapMode: Text.Wrap
text: directory
}
Button{
id:closeButton
height: 3*root.fontFactor*osSettings.bigFontSize
anchors.top: parent.top
anchors.topMargin: 0.5*mm
anchors.right: parent.right
anchors.rightMargin: 1*mm
text: "\uf057"
onClicked:{ready();imageDialog.destroy()}
// Text{
// id:directoryText
// anchors.bottom: parent.bottom
//// x:0.5*mm
//// y:0.5*mm
// width: imageDialog.width-3.5*root.fontFactor*osSettings.bigFontSize
// height:contentHeight
// font.pointSize: osSettings.bigFontSize
// wrapMode: Text.Wrap
// text: directory
// color: Material.primaryTextColor
// }
// Button{
// id:closeButton
// height: 2*root.fontFactor*osSettings.bigFontSize
// anchors.top: parent.top
// anchors.topMargin: 0.5*mm
// anchors.right: parent.right
// anchors.rightMargin: 1*mm
// text: "\uf057"
// onClicked:{
// ready();imageDialog.destroy()
// }
// }
FileDialog {
id: imageFileDialog
title: "Please choose a file"
folder: shortcuts.pictures
selectFolder: false
selectMultiple: true
onAccepted: {
imageUrl=imageFileDialog.fileUrls.toString();
ready();
}
}
// ListView {
// id: imageView
// x:0.5*mm
// y: 2.5*root.fontFactor*osSettings.bigFontSize//Math.max(directoryText.height, closeButton.height)+mm
// width: parent.width-2*mm
// height: parent.height-3*root.fontFactor*osSettings.bigFontSize
// boundsBehavior:Flickable.StopAtBounds
// clip: true
// model: imageModel
// delegate: imageItem
// ScrollBar.vertical: ScrollBar { }
// }
ListView {
id: imageView
x:0.5*mm
y: Math.max(directoryText.height, closeButton.height)+mm
width: imageDialog.width-2*mm
height: imageDialog.height-imageView.y-4*mm
clip: true
model: imageModel
delegate: imageItem
}
// FolderListModel{
// id: imageModel
// nameFilters: ["*.png", "*.jpg",".jpeg","*.JPG","*.gif"]
// sortField: FolderListModel.Time
// sortReversed:false
// showDotAndDotDot: true
// showDirs: true
// showDirsFirst: true
// folder:directory
// }
FolderListModel{
id: imageModel
nameFilters: ["*.png", "*.jpg",".jpeg","*.JPG","*.gif"]
sortField: FolderListModel.Time
sortReversed:false
showDotAndDotDot: true
showDirs: true
showDirsFirst: true
folder:directory
}
// BusyIndicator{
// id: imageBusy
// anchors.horizontalCenter: imageView.horizontalCenter
// anchors.top:imageView.top
// anchors.topMargin: 2*mm
// width: 2*root.fontFactor*osSettings.bigFontSize
// height: 2*root.fontFactor*osSettings.bigFontSize
// running:false
// }
BusyIndicator{
id: imageBusy
anchors.horizontalCenter: imageView.horizontalCenter
anchors.top:imageView.top
anchors.topMargin: 2*mm
width:10*mm
height: 10*mm
running:false
}
// Component{
// id:imageItem
// Item{
// width:imageView.width
// height: Math.max(fileImage.height,1.5*root.fontFactor*osSettings.bigFontSize)+2*mm
// Rectangle{
// id:imagetextRectangle
// color:"black"
// x:mm
// z:3
// opacity: fileIsDir?0:0.5
// width:imagetext.contentWidth
// height: imagetext.contentHeight
// anchors.bottom: fileImage.bottom
// }
// Text {
// id:imagetext
// x: mm//fileIsDir?11*mm:mm
// z:4
// text: fileIsDir?"\uf07b "+fileName:fileName
// width: fileIsDir?parent.width - 2.5*root.fontFactor*osSettings.bigFontSize :imageView.width-mm
// anchors.bottom: fileImage.bottom
// color: fileIsDir?Material.primaryTextColor:"white"
// font.pointSize: osSettings.bigFontSize
// wrapMode:Text.Wrap
// }
// Text {
// id:selected
// anchors.right:parent.right
// visible: attachImageURLs.indexOf(fileURL)>-1
// z:4
// text: "\u2713"
// width: 2*root.fontFactor*osSettings.bigFontSize
// anchors.top: fileImage.top
// color: "green"
// font.pointSize: 3*osSettings.bigFontSize
// }
Component{
id:imageItem
Item{
width:imageView.width
height:folderImage.height+2*mm
Rectangle{
id:imagetextRectangle
color:"black"
x:mm
z:3
opacity: fileIsDir?0:0.5
width:imagetext.contentWidth
height: imagetext.contentHeight
anchors.bottom: folderImage.bottom
}
Text {
id:imagetext
x:fileIsDir?11*mm:mm
z:4
text: fileName
width: fileIsDir?parent.width - 12*mm :imageView.width-mm
anchors.bottom: folderImage.bottom
color: fileIsDir?"black":"white"
font.pointSize: osSettings.bigFontSize
wrapMode:Text.Wrap
}
Text {
id:selected
anchors.right:parent.right
visible: attachImageURLs.indexOf(fileURL)>-1
z:4
text: "\u2713"
width: 10*mm
anchors.top: folderImage.top
color: "green"
font.pointSize: 3*osSettings.bigFontSize
}
// Image{id:fileImage
// width: imageView.width-mm
// fillMode:Image.PreserveAspectFit
// source:fileIsDir?"":fileURL
// }
Image{id:folderImage
width: fileIsDir?10*mm: imageView.width-mm
fillMode:Image.PreserveAspectFit
source:fileIsDir?"qrc:/images/folder-blue.png":fileURL
}
// MouseArea{
// anchors.fill: parent
// onClicked:{
// if (fileName==".."){
// imageModel.folder=imageModel.parentFolder;
// directory=imageModel.parentFolder
// }
// else if (fileIsDir){
// imageModel.folder=fileURL;
// directory=fileURL
// }
// else{
// if (multiple!=true){
// //attachImageURLs.push(fileURL);
// //attachImage(fileURL);
// imageUrls.push(fileURL);
// imageUrl=fileURL;
// ready();
// imageDialog.destroy()
// }
// else {
// if(selected.visible==true){
// imageUrls.splice(imageUrls.indexOf(fileURL,1))
// selected.visible=false
// }
// else{
// imageUrls.push(fileURL);
// selected.visible=true;
MouseArea{
anchors.fill: parent
onClicked:{
if (fileName==".."){
imageModel.folder=imageModel.parentFolder;
directory=imageModel.parentFolder
}
else if (fileIsDir){
imageModel.folder=fileURL;
directory=fileURL
}
else{
if (multiple!=true){
//attachImageURLs.push(fileURL);
//attachImage(fileURL);
imageUrls.push(fileURL);
imageUrl=fileURL;
ready();
imageDialog.destroy()
}
else {
if(selected.visible==true){
imageUrls.splice(imageUrls.indexOf(fileURL,1))
selected.visible=false
}
else{
imageUrls.push(fileURL);
selected.visible=true;
}
imageUrl=fileURL
}
}
}
}
}
}
// }
// imageUrl=fileURL
// }
// }
// }
// }
// }
// }
// Component.onCompleted: imageFileDialog.open()
}

View file

@ -22,13 +22,15 @@ Item {
h.push("file://"+ decodeURIComponent(message.imageUrls[n]).substring(5))
}
imageUrls=h;
if(imageUrls.length==1){
rootstack.currentIndex=0;newstab.active=true;
root.uploadSignal(imageUrls)
} else{
rootstack.currentIndex=2;fotostab.active=true;
root.uploadSignal(imageUrls)
}
rootstack.currentIndex=0;newstab.active=true;
root.uploadSignal(imageUrls.join(","))
// if(imageUrls.length==1){
// rootstack.currentIndex=0;newstab.active=true;
// root.uploadSignal(imageUrls)
// } else{
// rootstack.currentIndex=2;fotostab.active=true;
// root.uploadSignal(imageUrls)
// }
} else if (type==m_TEXT_MESSAGE){
rootstack.currentIndex=0;newstab.active=true;
root.sendtextSignal(message)

View file

@ -15,7 +15,6 @@ Item {
function startSyncTimer(interval){
syncTimer.interval=interval*60000;
//print("synctimer interval "+syncTimer.interval)
syncTimer.start()
}

View file

@ -0,0 +1,55 @@
// This file is part of Friendiqa
// https://git.friendi.ca/lubuwest/Friendiqa
// Copyright (C) 2020 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0
import QtQuick.Controls 2.15
import QtQuick.Controls.Material 2.12
import "qrc:/js/helper.js" as Helperjs
Dialog {
id: userReportDialog
anchors.centerIn: parent
property var newsitem:({})
title: qsTr("Block contact?")
standardButtons: Dialog.Ok | Dialog.Cancel
modal: true
onAccepted: {
Helperjs.updateData(root.db,"contacts",login.username,"statusnet_blocking", true,function(){},"id",newsitem.user.id)
xhr.setUrl(login.server);
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setApi("/api/v1/accounts/" + newsitem.user.id + "/block");
xhr.clearParams();
xhr.post();
}
onRejected: {close()}
Label {text: newsitem.user.name}
}

View file

@ -132,8 +132,8 @@ Page {
BusyIndicator{
id: contactBusy
anchors.centerIn:parent
width:10*mm
height: 10*mm
width: 1.5*root.fontFactor*osSettings.bigFontSize
height: 1.5*root.fontFactor*osSettings.bigFontSize
running: true
}
@ -159,6 +159,7 @@ Page {
function onProfileimagesourceChanged(){profileImage.source=profileimagesource}
}
}
Flow{id:buttonflow
anchors.right: parent.right
anchors.rightMargin: mm
@ -222,6 +223,7 @@ Page {
})
Helperjs.deleteData(root.db,"friendshiprequests",root.login.username,function(){},"id", contact.id)
//if (rootstack.currentIndex==1){root.friendsSignal(login.username)}
try{root.contactRefreshSignal();}catch(e){print("root.refreshSignal"+e)}
rootstackView.pop()
}
}
@ -236,6 +238,7 @@ Page {
})
Helperjs.deleteData(root.db,"friendshiprequests",root.login.username,function(){},"id", contact.id)
//if (rootstack.currentIndex==1){root.friendsSignal(login.username)}
try{root.contactRefreshSignal();}catch(e){print("root.refreshSignal"+e)}
rootstackView.pop()
}
}
@ -250,6 +253,7 @@ Page {
});
Helperjs.deleteData(root.db,"friendshiprequests",root.login.username,function(){},"id", contact.id)
//if (rootstack.currentIndex==1){root.friendsSignal(login.username)}
try{root.contactRefreshSignal();}catch(e){print("root.refreshSignal"+e)}
rootstackView.pop()
}
}
@ -264,6 +268,7 @@ Page {
});
Helperjs.updateData(root.db,"contacts",root.login.username,"isFriend",1,function(){},"id",contact.id)
try{root.contactRefreshSignal();}catch(e){print("root.refreshSignal"+e)}
//if (rootstack.currentIndex==1){root.friendsSignal(login.username)}
rootstackView.pop()
}
@ -281,10 +286,40 @@ Page {
});
Helperjs.updateData(root.db,"contacts",root.login.username,"isFriend",0,function(){},"id",contact.id)
//if (rootstack.currentIndex==1){root.friendsSignal(login.username)}
try{root.contactRefreshSignal();}catch(e){print("root.refreshSignal"+e)}
rootstackView.pop()
}
}
MButton{
id: blockbutton
visible:(contact.statusnet_blocking!=1)
height: 6*mm
text:qsTr("Block")
onClicked:{
contactBusy.running=true;
Helperjs.updateData(root.db,"contacts",root.login.username,"statusnet_blocking",true,function(){},"id",contact.id)
Helperjs.friendicaPostRequest(login,"/api/v1/accounts/" + contact.id + "/block",'',"POST",root,function(returnvalue){
});
try{root.contactRefreshSignal();}catch(e){print("root.refreshSignal"+e)}
rootstackView.pop()
}
}
MButton{
id: unblockbutton
visible:(contact.statusnet_blocking==1)
height: 6*mm
text:qsTr("Unblock")
onClicked:{
contactBusy.running=true;
Helperjs.updateData(root.db,"contacts",root.login.username,"statusnet_blocking",false,function(){},"id",contact.id)
Helperjs.friendicaPostRequest(login,"/api/v1/accounts/" + contact.id + "/unblock",'',"POST",root,function(returnvalue){
});
try{root.contactRefreshSignal();}catch(e){print("root.refreshSignal"+e)}
rootstackView.pop()
}
}
}//Flow end
Label {
@ -370,9 +405,6 @@ Page {
xhr.clearParams();
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setUrl(login.server);
// if(contact.isFriend==1 || contact.hasOwnProperty("acct")){
// xhr.setApi("/api/statuses/user_timeline");}
// else{xhr.setApi("/api/users/show");}
xhr.setApi("/api/statuses/user_timeline")
xhr.setParam("user_id",contact.id)
xhr.get();

View file

@ -104,9 +104,9 @@ Page {
id: conversationBusy
anchors.horizontalCenter: conversationView.horizontalCenter
anchors.top:conversationView.top
anchors.topMargin: 2*mm
width:10*mm
height: 10*mm
anchors.topMargin: mm
width: 2*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
running: true
}

View file

@ -0,0 +1,301 @@
// This file is part of Friendiqa
// https://git.friendi.ca/lubuwest/Friendiqa
// Copyright (C) 2020 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.5
import QtQuick.Controls 2.12
import QtQuick.Controls.Material 2.12
import "qrc:/js/helper.js" as Helperjs
import "qrc:/qml/genericqml"
Page{
id:imageDialog
property var attachImageURLs: []
// property var contacts: []
// property var groups: []
// property var contact_allow:login.permissions[0]
// property var contact_deny:login.permissions[1]
// property var group_allow:login.permissions[2]
// property var group_deny:login.permissions[3]
property int imageNo: 0
function uploadImage(imageid){
if(imageUploadModel.get(imageid).uploaded==true){
imageNo=imageNo+1;
if(imageNo<imageUploadModel.count){
uploadImage(imageNo);
}
} else{
xhr.setUrl(login.server);
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setApi("/api/media/upload");
xhr.clearParams();
//if (group_allow.length>0) {xhr.setParam("group_allow", Helperjs.cleanArray(group_allow))};
//if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))};
//if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))};
//if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))};
xhr.setImageFileParam("media", imageUploadModel.get(imageid).imageUrl);
xhr.setImageFileParam("angle", imageUploadModel.get(imageid).imageRotation);
xhr.post();
}
}
function updateAltText(imageid, media){print("media "+media + " alt_text "+imageUploadModel.get(imageid).description)
xhr.setUrl(login.server);
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setApi("/api/media/metadata/create");
xhr.clearParams();
xhr.setParam("JSON",JSON.stringify({media_id:media,alt_text:{text:imageUploadModel.get(imageid).description}}));
xhr.postJSON();
}
function attach(){
imagePicking=true;
var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+
osSettings.imagePickQml+'{multiple : false;onReady: {'+
'attachImage(imageUrl)}}',imageDialog,"imagePicker");
imagePicker.pickImage()
}
function attachImage(url){
if (url.indexOf(",")>0){
let urlArray=url.split(",");
for (let file in urlArray){attachImage(urlArray[file])}
} else{
if(url!=""){
imageUploadModel.append({"imageUrl":url,"description":"","imageUploaded":false,"imageRotation":0})
}
}
}
y:1
width: messageColumn.width-1.5*root.fontFactor*osSettings.bigFontSize
height: 15*root.fontFactor*osSettings.bigFontSize//root.height/2-1.5*root.fontFactor*osSettings.bigFontSize
onVisibleChanged: {if (visible==false){
imageUploadModel.clear();
imageNo=0;
}}
Connections{
target:xhr
function onError(data,url,api,code){
print("error "+data);
}
function onSuccess(data,api){
if (api=="/api/media/upload" ){print("data "+data);
let obj=JSON.parse(data);
messageSend.media_ids.push(obj.media_id);
if(imageUploadModel.get(imageNo).description!==""){
try{
updateAltText(imageNo,obj.media_id_string)
}catch(e){}
}
else{
imageUploadModel.set(imageNo,{"imageUploaded":true});
imageNo=imageNo+1;
if(imageNo<imageUploadModel.count){
uploadImage(imageNo);
}
}
} else if(api=="/api/media/metadata/create"){
imageUploadModel.set(imageNo,{"imageUploaded":true});
imageNo=imageNo+1;
if(imageNo<imageUploadModel.count){
uploadImage(imageNo);
}
}
}
}
ListView{
id: imageUploadView
x: root.fontFactor*osSettings.bigFontSize
y: 0.5*root.fontFactor*osSettings.bigFontSize
width: imageDialog.width-1.5*root.fontFactor*osSettings.bigFontSize
height: parent.height -(3*root.fontFactor*osSettings.bigFontSize)
model: imageUploadModel
delegate: imageDelegate
footer: imageFooter
clip:true
orientation: ListView.Horizontal
spacing: mm
DropArea{
anchors.fill: parent
onDropped: {
if (drop.keys.includes('text/uri-list')){
var urllist=drop.text.split('\n');
for(var i=0;i< urllist.length;i++){
var droptext = urllist[i].replace(/(\r\n|\n|\r)/gm, ",");
attachImage(droptext)
}
}
}
}
}
BusyIndicator{
id: uploadBusy
running: false
anchors.horizontalCenter: imageUploadView.horizontalCenter
anchors.top:imageUploadView.top
anchors.topMargin: root.fontFactor*osSettings.bigFontSize
width: 2.5*root.fontFactor*osSettings.bigFontSize
height: 2.5*root.fontFactor*osSettings.bigFontSize
}
ListModel{
id: imageUploadModel
}
Component{
id: imageDelegate
Rectangle{
width: Math.max(10*root.fontFactor*osSettings.bigFontSize,uploadImage.width)
height:imageUploadView.height-4*root.fontFactor*osSettings.bigFontSize
color: Material.backgroundColor
Image{
id: uploadImage
width: parent.width //root.width/2-mm
height: imageUploadView.height-(3*root.fontFactor*osSettings.bigFontSize+2*mm)
fillMode: Image.PreserveAspectFit
source:imageUrl
transform: Rotation {id:rotator; origin.x: uploadImage.width/2; origin.y: uploadImage.height/2; angle: imageRotation}
onVisibleChanged: descriptionInput.focus=true;
}
Rectangle{//rotation
width: 2*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
visible: uploadImage.source!=""
anchors.bottom: uploadImage.bottom
anchors.right: uploadImage.right
color: "black"
opacity: 0.5
Text{anchors.centerIn:parent;text: "\uf01e";color: "white"}
MouseArea{
anchors.fill:parent;
onClicked:{
rotator.angle+=90;
imageRotation+=90
imageUploadModel.set(index,{"imageRotation":imageRotation});
}
}
}
Rectangle{//remove
width: 2*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
visible: uploadImage.source!=""
anchors.bottom: uploadImage.bottom
anchors.left: uploadImage.left
color: "black"
opacity: 0.5
Text{anchors.centerIn:parent;text: "\uf00d";color: "white"}
MouseArea{
anchors.fill:parent;
onClicked:{
imageUploadModel.remove(index)
}
}
}
Text {
id:uploadedArrow
anchors.right:uploadImage.right
visible: imageUploaded
z:4
text: "\u2713"
width: root.fontFactor*osSettings.bigFontSize
anchors.top: parent.top
color: "green"
font.pointSize: 3*osSettings.bigFontSize
}
Rectangle{
id:descriptionRectangle
color: Material.backgroundColor
border.color: "grey"
anchors.top: uploadImage.bottom
anchors.topMargin: mm
width: parent.width //root.width/2-mm //Math.max(root.width/2-mm, descriptionInput.contentWidth);
height: 2.5*root.fontFactor*osSettings.bigFontSize //5*mm;
TextField{
id: descriptionInput
anchors.fill: parent
anchors.margins: 0.5*mm
font.pointSize: osSettings.systemFontSize
selectByMouse: true
placeholderText: qsTr("Description")
text:description!=""?description:""
onTextChanged: imageUploadModel.set(index,{"description":descriptionInput.text});
}
}
}
}
Component{
id: imageFooter
BlueButton{
width: 5*root.fontFactor*osSettings.bigFontSize
height:imageUploadView.height-3*root.fontFactor*osSettings.bigFontSize
color: Material.backgroundColor
text:"\u002b"
fontSize: 3*osSettings.bigFontSize
onClicked:{attach()}
}
}
Button{
id:uploadButton
height: 2*root.fontFactor*osSettings.bigFontSize
x: root.fontFactor*osSettings.bigFontSize
anchors.top:imageUploadView.bottom
anchors.topMargin: mm
text: qsTr("Upload")
font.pointSize: osSettings.bigFontSize
onClicked:{
{newimageProgress.visible=true;
if (imageUploadModel.count>0){
uploadImage(imageNo)
}}
}
}
ProgressBar{
id: newimageProgress
width: 5*root.fontFactor*osSettings.bigFontSize
height: root.fontFactor*osSettings.systemFontSize//buttonRow.height
anchors.top: parent.top
visible: false
value: imageNo/imageUploadModel.count
}
}

View file

@ -38,20 +38,20 @@ import "qrc:/js/helper.js" as Helperjs
import "qrc:/js/smiley.js" as Smileyjs
import "qrc:/js/news.js" as Newsjs
import "qrc:/qml/genericqml"
import "qrc:/qml/newsqml"
Rectangle{
color:Material.dialogColor
width:parent.width
height: conversation || (newsSwipeview.stacktype!="Notifications")?messageColumn.height+2*mm:0
height: messageColumn.height+2*mm
id:messageSend
visible:conversation || (newsSwipeview.stacktype!="Notifications")||(newstab.newstabstatus!="Search")?true:false
visible:conversation || (newstab.newstabstatus!="Search")?true:false
property string parentId: ""
property bool textfocus: false
property bool conversation: false
property string reply_to_user:""
property alias bodyMessage: bodyField.text
property var attachImageURLs: [];
property var media_ids:[]
property var contacts: []
property var groups: []
property var contact_allow:login.hasOwnProperty("permissions")?login.permissions[0]:[]
@ -66,11 +66,8 @@ Rectangle{
}
function sendUrls(urls){
if((urls.length==1 && attachImageURLs.length==0)){
attachImage(urls);
attachImageURLs.push(urls);
messageSend.state="active";
}
}
function sendtext(text){
@ -84,48 +81,36 @@ Rectangle{
}
function attachImage(url){
imageAttachment.source=url.toString();
if(url!=""){
imageUploadDialog.visible=true;
imageUploadDialog.attachImage(url)
}
}
function statusUpdate(title,status,in_reply_to_status_id,attachImageURL) {
function statusUpdate(title,status,in_reply_to_status_id) {
//xhr.url= login.server + "/api/statuses/update.json";
try{newsBusy.running=true;conversationBusy.running=true}catch(e){}
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setUrl(login.server);
//if (in_reply_to_status_id==""){
xhr.setApi("/api/statuses/update");
xhr.clearParams();
xhr.setParam("source", "Friendiqa");
xhr.setParam("htmlstatus", status);
if (parentId!="") {xhr.setParam("in_reply_to_status_id", parentId)};
if (title!=="") {xhr.setParam("title", title)};
if (group_allow.length>0) {xhr.setParam("group_allow", Helperjs.cleanArray(group_allow))};
if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))};
if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))};
if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))};
if (attachImageURL.length>0) {
for (var image in attachImageURL){
xhr.setImageFileParam("media", attachImageURL[image]);
xhr.setImageFileParam("angle", rotator.angle.toString());
}
}
xhr.post();
Newsjs.storeHashtags(login,db,status,root)
// }else {
// xhr.setApi("/api/v1/statuses");
// xhr.clearParams();
// xhr.setParam("status", status);
// xhr.setParam("in_reply_to_id", in_reply_to_status_id);
// xhr.post();
// Newsjs.storeHashtags(login,db,status,root)
// messageSend.destroy()
// }
messageSend.destroy()
xhr.setApi("/api/statuses/update");
xhr.clearParams();
xhr.setParam("source", "Friendiqa");
xhr.setParam("htmlstatus", status);
if (parentId!="") {xhr.setParam("in_reply_to_status_id", parentId)};
if (title!=="") {xhr.setParam("title", title)};
if (group_allow.length>0) {xhr.setParam("group_allow", Helperjs.cleanArray(group_allow))};
if (group_deny.length>0) {xhr.setParam("group_deny", Helperjs.cleanArray(group_deny))};
if (contact_allow.length>0) {xhr.setParam("contact_allow", Helperjs.cleanArray(contact_allow))};
if (contact_deny.length>0) {xhr.setParam("contact_deny", Helperjs.cleanArray(contact_deny))};
if (media_ids.length>0) {
xhr.setParam("media_ids", media_ids.join());
}
xhr.post();
Newsjs.storeHashtags(login,db,status,root)
}
function dmUpdate(title,text,replyto,screen_name,attachImageURL) {
function dmUpdate(title,text,replyto,screen_name) {
newsBusy.running=true;
//xhr.url= login.server + "/api/direct_messages/new.json";
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setUrl(login.server);
xhr.setApi("/api/direct_messages/new");
@ -133,7 +118,6 @@ Rectangle{
xhr.setParam("text", text);
xhr.setParam("screen_name", screen_name);
if (parentId!="") {xhr.setParam("replyto", replyto)};
//if (title!=="") {xhr.setParam("title", title)};
xhr.post();
}
@ -147,8 +131,6 @@ Rectangle{
messageSend.reply_to_user="";
messageSend.parentId="";
bodyField.text="";
attachImageURLs.pop();
imageAttachment.source=""
}
}
@ -183,9 +165,9 @@ Rectangle{
onDropped: {
if (messageSend.state==""){messageSend.state="active"}
if (drop.keys.includes('text/uri-list')){
var droptext = drop.text.replace(/(\r\n|\n|\r)/gm, "");
attachImageURLs.push(droptext);
attachImage(droptext)}
var droptext = drop.text.replace(/(\r\n|\n|\r)/gm, ",");
imageUploadDialog.visible=true;
attachImage(droptext)}
else if (drop.keys.includes('text/html')){
bodyField.append(drop.html)}
else if (drop.keys.includes('text/plain')){
@ -204,7 +186,35 @@ Rectangle{
horizontalAlignment:Text.AlignHCenter
text: !conversation &&newsSwipeview.stacktype?qsTr(newsSwipeview.stacktype):""
font.pointSize: osSettings.bigFontSize
}
BlueButton{
width: root.fontFactor*osSettings.bigFontSize
height:stackTypeDescription.height
anchors.left: stackTypeDescription.left
anchors.leftMargin: 2*root.fontFactor*osSettings.bigFontSize
visible: newsSwipeview.currentIndex!=0
text:"\uf053"
fontColor: Material.hintTextColor
border.color: "transparent"
color:"transparent"
radius:0
onClicked: {newsSwipeview.currentIndex=newsSwipeview.currentIndex-1}
}
BlueButton{
width: root.fontFactor*osSettings.bigFontSize
height:stackTypeDescription.height
anchors.right: stackTypeDescription.right
anchors.rightMargin: 2*root.fontFactor*osSettings.bigFontSize
visible: newsSwipeview.currentIndex!=newsSwipeview.length-1
text:"\uf054"
fontColor: Material.hintTextColor
border.color: "transparent"
color:"transparent"
radius:0
onClicked: {newsSwipeview.currentIndex=newsSwipeview.currentIndex+1}
}
}
TextArea{
id:receiverLabel
width: messageColumn.width
@ -222,7 +232,7 @@ Rectangle{
width: parent.width-mm
font.pointSize: osSettings.systemFontSize
placeholderText: qsTr("Title (optional)")
visible: false//(parentId === "") && (bodyField.length>1)
visible: false
onVisibleChanged: if ((visible==true)&&(conversation==true)){
conversationView.contentY=conversationView.contentY+titleField.height
}
@ -263,8 +273,9 @@ Rectangle{
onActiveFocusChanged:{
if (activeFocus==true){
if (messageSend.ListView.view==null){
if (newsitem.ListView.view==null){}
else {newsitem.ListView.view.contentY=newsitem.ListView.view.contentY+newsitem.height/2}
if ((typeof newsitem == 'undefined') || (newsitem.ListView.view==null)){}
else {
newsitem.ListView.view.contentY=newsitem.ListView.view.contentY+newsitem.height/2}
}
else if (conversation==true){
if(parentId==""){setParent(conversationModel.get(0).newsitemobject);}
@ -272,7 +283,7 @@ Rectangle{
try{conversationView.contentY=conversationView.contentY+20*mm}catch(e){}
} else if (textfocus==false){
messageSend.state="active";
newsView.positionViewAtBeginning();
messageSend.ListView.view.positionViewAtBeginning();
}
else{
messageSend.ListView.view.contentY=messageSend.ListView.view.contentY+8*mm
@ -301,8 +312,8 @@ Rectangle{
id:contactSelector
visible: false
z:3
x:2*root.fontFactor*osSettings.bigFontSize//8*mm
width: parent.width-2.2*root.fontFactor*osSettings.bigFontSize//9*mm
x:2*root.fontFactor*osSettings.bigFontSize
width: parent.width-2.2*root.fontFactor*osSettings.bigFontSize
height: messageSend.height/2
model:contactModel
function processContactSelection(contact){
@ -328,8 +339,8 @@ Rectangle{
id: tagSelector
visible: false
z:3
x:2*root.fontFactor*osSettings.bigFontSize//8*mm
width: parent.width-2.2*root.fontFactor*osSettings.bigFontSize//9*mm
x:2*root.fontFactor*osSettings.bigFontSize
width: parent.width-2.2*root.fontFactor*osSettings.bigFontSize
height: messageSend.height/2
model:tagModel
clip: true
@ -343,52 +354,11 @@ Rectangle{
}
ListModel{id:tagModel}
Item{
id:imageAttachment;
property alias source:realimage.source
//property alias angle:rotator.angle
visible: source!=""
width: 45*mm
height: 45*mm;
MouseArea{
anchors.fill: parent
onClicked: {
attachImageURLs.splice(attachImageURLs.indexOf(source),1);
imageAttachment.source=""
}
}
Image{id:realimage
source:"";
x:2*mm;
width: 45*mm;
height: source==""?0:45*mm;
fillMode: Image.PreserveAspectFit;
transform: Rotation {id:rotator; origin.x: 22.5*mm; origin.y: 22.5*mm; angle: 0}
}
Rectangle{
width: 5*mm
height: 5*mm
visible: imageAttachment.source!=""
anchors.bottom: imageAttachment.bottom
anchors.right: imageAttachment.right
color: "black"
opacity: 0.5
Text{anchors.centerIn:parent;text: "\uf01e";color: "white"}
MouseArea{
anchors.fill:parent;
onClicked:{
rotator.angle+=90;
}
}
}
}
Row{
id:buttonRow
visible:false //(bodyField.length>1)||(attachImageURLs.length>0)
visible:false
spacing: mm
height: 2.5*root.fontFactor*osSettings.bigFontSize//12*mm
height: 2.5*root.fontFactor*osSettings.bigFontSize
x: 0.5*mm
// MButton{id:permButton //Permissions not working in Friendica 02/2022
@ -398,25 +368,6 @@ Rectangle{
// text: ((contact_allow.length==0)&&(contact_deny.length==0)&&(group_allow.length==0)&&(group_deny.length==0))?"\uf09c":"\uf023"
// onClicked: { if (permissionDialog.visible==false){permissionDialog.visible=true} else{permissionDialog.visible=false}}
// }
MButton {
id: attachButton
height: 2*root.fontFactor*osSettings.bigFontSize
width: 2*root.fontFactor*osSettings.bigFontSize
text: "\uf03e"
visible:(newsSwipeview.stacktype!="DirectMessages")
onClicked: {
if (attachImageURLs.length>0){//Server currently accepts only one attachment
Helperjs.showMessage( qsTr("Error"),qsTr("Only one attachment supported at the moment.\n Remove other attachment first!"), messageColumn)
}
else{
root.imagePicking=false;
var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+
osSettings.imagePickQml+'{multiple : false;onReady: {attachImageURLs.push(imageUrl);'+
'attachImage(imageUrl)}}',root,"imagePicker");
imagePicker.pickImage()
}
}
}
MButton{
id:smileyButton
@ -433,6 +384,19 @@ Rectangle{
width: 2*root.fontFactor*osSettings.bigFontSize
onClicked: {if (tagSelector.visible==false){hashtagmenu()} else{tagSelector.visible=false}}
}
MButton{
id:imagesButton
visible:(newsSwipeview.stacktype!="DirectMessages")
text: "\uf03e"
height: 2*root.fontFactor*osSettings.bigFontSize
width: 2*root.fontFactor*osSettings.bigFontSize
onClicked: {
if (imageUploadDialog.visible==false){
imageUploadDialog.visible=true;
imageUploadDialog.attach()
}
else{imageUploadDialog.visible=false}}
}
MButton {
id: cancelButton
@ -445,10 +409,11 @@ Rectangle{
bodyField.text="";
messageSend.state="";
permissionDialog.visible=false;
smileyDialog.visible=false;
imageUploadDialog.visible=false;
receiverLabel.visible=false;
reply_to_user="";
attachImage("");
attachImageURLs.pop();
media_ids=[]
}
}
}
@ -463,9 +428,9 @@ Rectangle{
var dmbody=bodyField.getText(0,bodyField.length);
if (conversation || newsSwipeview.stacktype!=="DirectMessages"){
if (parentId!=""){
statusUpdate(title,dmbody,parentId,attachImageURLs)
statusUpdate(title,dmbody,parentId)
}else{
statusUpdate(title,body,parentId,attachImageURLs)}
statusUpdate(title,body,parentId)}
}else {
if (reply_to_user!=""){dmUpdate(title,dmbody,parentId,reply_to_user)}
else{Helperjs.showMessage(qsTr("Error"),qsTr("No receiver supplied!"),root)}
@ -478,6 +443,7 @@ Rectangle{
}
PermissionDialog{id:permissionDialog;x:mm;visible: false}
SmileyDialog{id:smileyDialog;x:mm;visible: false}
MessageImageUploadDialog{id:imageUploadDialog;visible: false}
}
Component.onCompleted:{
root.replySignal.connect(setParent);
@ -497,7 +463,7 @@ Rectangle{
target: buttonRow; visible:true
}
PropertyChanges {
target: titleField; visible:(newsSwipeview.stacktype!="DirectMessages")//true
target: titleField; visible:(newsSwipeview.stacktype!="DirectMessages")
}
PropertyChanges {
target: receiverLabel; visible:(newsSwipeview.stacktype=="DirectMessages");

View file

@ -29,7 +29,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.11
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls.Material 2.12
import "qrc:/js/news.js" as Newsjs
@ -51,9 +51,9 @@ Rectangle{
id: newsBusy
anchors.horizontalCenter: parent.horizontalCenter
anchors.top:parent.top
anchors.topMargin: 2*mm
width:10*mm
height: 10*mm
anchors.topMargin: mm
width: 2*root.fontFactor*osSettings.bigFontSize
height: 2*root.fontFactor*osSettings.bigFontSize
z:2
running: false
}
@ -67,7 +67,8 @@ Rectangle{
try{ Newsjs.newsfromdb(root.db,root.login,0, function(dbnews,lastid){
lastnewsid=lastid;
showNews(dbnews)
})}catch(e){Helperjs.showMessage("Error",e,root)};
})}catch(e){//Helperjs.showMessage("Error",e,root)
};
break;
case "conversation":
newsStack.updateMethodNews="conversation";
@ -219,13 +220,30 @@ Rectangle{
Connections{
target:xhr
function onError(data,url,api,code){
if (data !="contactlist"){Helperjs.showMessage(qsTr("Network Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root);}
//if (data !="contactlist"){Helperjs.showMessage(qsTr("Network Error"),"API:\n" +login.server+api+"\n Return: \n"+data,root);}
newsBusy.running=false;
}
function onSuccess(data,api){
// downloadNotice.text=downloadNotice.text+ "\n xhr finished "+Date.now();
Service.processNews(api,data)
replySignal("")
const newsApiArray=["/api/statuses/friends_timeline",
"/api/direct_messages/all",
"/api/direct_messages/conversation",
"/api/direct_messages/new",
"/api/friendica/notification",
"/api/statuses/user_timeline",
"/api/conversation/show",
"/api/search",
"/api/statuses/public_timeline",
"/api/favorites",
"/api/statuses/replies",
"/api/lists/statuses",
"/api/statuses/update",
"/api/direct_messages/new"
];
if(newsApiArray.includes(api)){
Service.processNews(api,data)
replySignal("")
}
}
}
@ -301,9 +319,7 @@ Rectangle{
anchors.margins: 0.5*mm
clip: true
spacing: 0
header:
MessageSend{id:messagesend;onHeightChanged: newsView.positionViewAtBeginning()}
header:MessageSend{id:messagesend;onHeightChanged: {if(state=="active"){newsView.positionViewAtBeginning()}}}
footer: footerComponent
model: newsModel
delegate: Newsitem{}
@ -349,6 +365,7 @@ Rectangle{
if (newsSwipeview.stacktype=="Home"){
Newsjs.getLastNews(root.login,root.db,function(currentlastnews){
//print("currentlastnews "+currentlastnews+ " lastnewsid "+lastnewsid)
if (currentlastnews>lastnewsid){
if(currentnewstabstatus=="Timeline"){
try{ Newsjs.newsfromdb(root.db,root.login,0, function(dbnews,lastid){
@ -361,7 +378,7 @@ Rectangle{
lastnewsid=lastid;
showNews(news)});
}
} else {
} else {
Service.updateView(currentnewstabstatus)
}
});

View file

@ -273,7 +273,7 @@ Item {
//Bottom row for buttons
Row{id:controlrow
anchors.top:friendicaActivities.bottom
height: root.fontFactor*osSettings.bigFontSize
height: 1.5*root.fontFactor*osSettings.bigFontSize
CheckBox{
id:likeCheckbox
width:newsitem.width/5
@ -281,12 +281,13 @@ Item {
visible: ((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3))? true:false
checked:(model.newsitemobject.friendica_activities_view.self.liked==1)?true:false
indicator: Rectangle{
height: parent.height
implicitWidth: newsitem.width/5
implicitHeight:root.fontFactor*osSettings.bigFontSize
color:"transparent"
Text{
anchors.centerIn: parent
font.pointSize: osSettings.systemFontSize
font.pointSize: osSettings.bigFontSize
font.family:fontAwesome.name
color:likeCheckbox.checked?Material.primaryTextColor: Material.secondaryTextColor
text:likeCheckbox.checked?"\uf118"+"!":"\uf118"
@ -309,12 +310,13 @@ Item {
visible: ((newsitemobject.messagetype==0)||(newsitemobject.messagetype==3))? true:false
checked: (newsitemobject.friendica_activities_view.self.disliked==1)?true:false
indicator: Rectangle{
height: parent.height
implicitWidth: newsitem.width/5
implicitHeight:root.fontFactor*osSettings.bigFontSize
color:"transparent"
Text{
anchors.centerIn: parent
font.pointSize: osSettings.systemFontSize
font.pointSize: osSettings.bigFontSize
font.family:fontAwesome.name
color:dislikeCheckbox.checked?Material.primaryTextColor: Material.secondaryTextColor
text: dislikeCheckbox.checked?"\uf119"+"!":"\uf119"
@ -337,12 +339,13 @@ Item {
width: newsitem.width/5
height: parent.height
indicator:Rectangle{
height: parent.height
implicitWidth: newsitem.width/5
implicitHeight:root.fontFactor*osSettings.bigFontSize
color:"transparent"
Text{
anchors.centerIn: parent
font.pointSize: osSettings.systemFontSize
font.pointSize: osSettings.bigFontSize
font.family:fontAwesome.name
color: favoritedCheckbox.checked?Material.primaryTextColor: Material.secondaryTextColor
text:"\uf005"
@ -365,7 +368,7 @@ Item {
id:replysymbol
color: Material.secondaryTextColor
anchors.centerIn: parent
font.pointSize: osSettings.systemFontSize
font.pointSize: osSettings.bigFontSize
font.family:fontAwesome.name
text: "\uf112"
}
@ -398,7 +401,7 @@ Item {
id:newsmenusymbol
color: Material.secondaryTextColor
anchors.centerIn: parent
font.pointSize: osSettings.systemFontSize
font.pointSize: osSettings.bigFontSize
font.family:fontAwesome.name
text: "\uf142"
}
@ -429,6 +432,27 @@ Item {
})
}
}
Action {
text: qsTr("Block contact")
onTriggered: {
var component = Qt.createComponent("qrc:/qml/newsqml/BlockUser.qml");
var userblockdialog = component.createObject(root,{"newsitem": newsitemobject});
userblockdialog.open()
// try{
// var msg = {'deleteId': index, 'model': newsitem.ListView.view.model};
// conversationWorker.sendMessage(msg);
// }catch(e){print("block "+e)
// }
}
}
Action {
text: qsTr("Report contact")
onTriggered: {
var component = Qt.createComponent("qrc:/qml/newsqml/ReportUser.qml");
var userreportdialog = component.createObject(root,{"newsitem": newsitemobject});
userreportdialog.open()
}
}
Action {
text: qsTr("Conversation")
onTriggered: {
@ -450,6 +474,15 @@ Item {
Newsjs.favorite(login,false,newsitemobject.id,root);model.newsitemobject.favorited=0}
}
}
Action{
text:qsTr("Calendar Entry")
onTriggered:{
rootstack.currentIndex=3;
bar.currentIndex=3;
eventcreateSignal(newsitemobject);
}
}
Menu{
title: qsTr("Attending")
width: 10*root.fontFactor*osSettings.systemFontSize
@ -481,7 +514,7 @@ Item {
text: qsTr("Delete")
onTriggered: {
Newsjs.deleteNews(root.login,root.db,newsitemobject.id,newsitemobject.messagetype,root,function(reply){
var msg = {'deleteId': index, 'model': newsModel};
var msg = {'deleteId': index, 'model': newsitem.ListView.view.model};
newsWorker.sendMessage(msg);
})
}

View file

@ -0,0 +1,77 @@
// This file is part of Friendiqa
// https://git.friendi.ca/lubuwest/Friendiqa
// Copyright (C) 2020 Marco R. <thomasschmidt45@gmx.net>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import QtQuick 2.0
import QtQuick.Controls 2.15
import QtQuick.Controls.Material 2.12
import "qrc:/js/helper.js" as Helperjs
Dialog {
id: userReportkDialog
anchors.centerIn: parent
property var newsitem:({})
title: qsTr("Report contact?")
standardButtons: Dialog.Ok | Dialog.Cancel
modal: true
onAccepted: {
let statusArray=[];statusArray.push(newsitem.id.toString());
xhr.setUrl(login.server);
xhr.setLogin(login.username+":"+Qt.atob(login.password));
xhr.setApi("/api/v1/reports");
xhr.clearParams();
xhr.setParam("account_id",newsitem.user.id);
//xhr.setParam("status_ids",JSON.stringify(statusArray));
xhr.setParam("comment",comment.text);
xhr.setParam("category",categoryCombo.currentText);
xhr.post();
}
onRejected: {close()}
Column{
height: nameLabel.height+comment.height+categoryCombo.height
Label {id:nameLabel;text: newsitem.user.name}
TextField {
id: comment
font.pointSize: osSettings.systemFontSize
selectByMouse: true
placeholderText: qsTr("comment")
}
ComboBox{
id: categoryCombo
width: 6*root.fontFactor*osSettings.bigFontSize
height: 1.5*root.fontFactor*osSettings.bigFontSize
font.pointSize: osSettings.systemFontSize
model: [qsTr("illegal"),qsTr("spam"), qsTr("violation")]
}
}
}

View file

@ -79,9 +79,15 @@ Page{
function attachImage(url){
imageUploadModel.append({"imageUrl":url,"description":""})
if (url.indexOf(",")>0){
let urlArray=url.split(",");
for (let file in urlArray){attachImage(urlArray[file])}
} else{
if(url!=""){
imageUploadModel.append({"imageUrl":url,"description":"","imageUploaded":false,"imageRotation":0})
}
}
}
//border.color: "grey"
y:1
width:root.width-mm
@ -277,23 +283,18 @@ Page{
}
Component{
id: imageFooter
Image{
id: footerImage
height: root.width/4
width: root.width/4 //15*mm
//15*mm
fillMode: Image.PreserveAspectFit
source:"qrc:/images/addImage.png"
MouseArea{
anchors.fill: parent
onClicked:{
imagePicking=true;
var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+
osSettings.imagePickQml+'{multiple : false;onReady: {attachImageURLs.push(imageUrl);'+
'attachImage(imageUrl)}}',imageDialog,"imagePicker");
imagePicker.pickImage()
}
}
BlueButton{
width: 5*root.fontFactor*osSettings.bigFontSize
height:imageUploadView.height-3*root.fontFactor*osSettings.bigFontSize
color: Material.backgroundColor
text:"\u002b"
fontSize: 3*osSettings.bigFontSize
onClicked:{
imagePicking=true;
var imagePicker = Qt.createQmlObject('import QtQuick 2.0; import "qrc:/qml/genericqml";'+
osSettings.imagePickQml+'{multiple : false;onReady: {'+
'attachImage(imageUrl)}}',imageDialog,"imagePicker");
imagePicker.pickImage()}
}
}