Version 0.002 with working FriendsTabView
This commit is contained in:
parent
bc4adba50c
commit
42de63fe63
|
@ -1,387 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE QtCreatorProject>
|
|
||||||
<!-- Written by QtCreator 4.1.0, 2016-09-26T21:14:21. -->
|
|
||||||
<qtcreator>
|
|
||||||
<data>
|
|
||||||
<variable>EnvironmentId</variable>
|
|
||||||
<value type="QByteArray">{feb2a9e8-6b42-4908-9ecd-b9e4d47e7412}</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
|
||||||
<value type="int">0</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
|
||||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
|
||||||
<value type="QString" key="language">Cpp</value>
|
|
||||||
<valuemap type="QVariantMap" key="value">
|
|
||||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
|
||||||
</valuemap>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
|
||||||
<value type="QString" key="language">QmlJS</value>
|
|
||||||
<valuemap type="QVariantMap" key="value">
|
|
||||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
|
||||||
</valuemap>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
|
||||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
|
||||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
|
||||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
|
||||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
|
||||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
|
||||||
<valuemap type="QVariantMap"/>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Android für armeabi-v7a (GCC 4.9, Qt 5.5.1)</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Android für armeabi-v7a (GCC 4.9, Qt 5.5.1)</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{10172d6f-97b2-4745-a95e-fc1020afb172}</value>
|
|
||||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
|
|
||||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
|
||||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/pankraz/bin</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
|
|
||||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
|
|
||||||
<value type="QString">-w</value>
|
|
||||||
<value type="QString">-r</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Anwendungsdaten kopieren</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.AndroidPackageInstallationStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.3">
|
|
||||||
<value type="QString" key="BuildTargetSdk">android-18</value>
|
|
||||||
<value type="QString" key="KeystoreLocation"></value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Android-APK erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.AndroidBuildApkStep</value>
|
|
||||||
<value type="int" key="Qt4ProjectManager.AndroidDeployQtStep.DeployQtAction">2</value>
|
|
||||||
<value type="bool" key="UseGradle">false</value>
|
|
||||||
<value type="bool" key="VerboseOutput">false</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">4</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
|
|
||||||
<value type="QString">-w</value>
|
|
||||||
<value type="QString">-r</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
|
||||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
|
||||||
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/pankraz/ownCloud/clientsync/Friendiqa/v0.001/bin</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">false</value>
|
|
||||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">false</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
|
|
||||||
<value type="QString">-w</value>
|
|
||||||
<value type="QString">-r</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Anwendungsdaten kopieren</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.AndroidPackageInstallationStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.3">
|
|
||||||
<value type="QString" key="BuildTargetSdk">android-18</value>
|
|
||||||
<value type="QString" key="KeystoreLocation">/home/pankraz/ownCloud/clientsync/android_release.keystore</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Android-APK erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.AndroidBuildApkStep</value>
|
|
||||||
<value type="int" key="Qt4ProjectManager.AndroidDeployQtStep.DeployQtAction">2</value>
|
|
||||||
<value type="bool" key="UseGradle">false</value>
|
|
||||||
<value type="bool" key="VerboseOutput">false</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">4</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
|
|
||||||
<value type="QString">-w</value>
|
|
||||||
<value type="QString">-r</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
|
||||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
|
||||||
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/pankraz/ownCloud/clientsync/Friendiqa/v0.001/build-friendiqa-Android_f_r_armeabi_v7a_GCC_4_9_Qt_5_5_1-Profile</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">qmake</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary">true</value>
|
|
||||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.SeparateDebugInfo">true</value>
|
|
||||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.UseQtQuickCompiler">false</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
|
|
||||||
<value type="QString">-w</value>
|
|
||||||
<value type="QString">-r</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">false</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments"></value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.2">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Anwendungsdaten kopieren</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.AndroidPackageInstallationStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.3">
|
|
||||||
<value type="QString" key="BuildTargetSdk">android-23</value>
|
|
||||||
<value type="QString" key="KeystoreLocation"></value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Android-APK erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QmakeProjectManager.AndroidBuildApkStep</value>
|
|
||||||
<value type="int" key="Qt4ProjectManager.AndroidDeployQtStep.DeployQtAction">2</value>
|
|
||||||
<value type="bool" key="UseGradle">false</value>
|
|
||||||
<value type="bool" key="VerboseOutput">false</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">4</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
|
||||||
<valuelist type="QVariantList" key="Qt4ProjectManager.MakeStep.AutomaticallyAddedMakeArguments">
|
|
||||||
<value type="QString">-w</value>
|
|
||||||
<value type="QString">-r</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="Qt4ProjectManager.MakeStep.Clean">true</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
|
||||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeCommand"></value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Profile</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
|
||||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
|
||||||
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment auf Android-Gerät</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.AndroidDeployQtStep</value>
|
|
||||||
<value type="bool" key="UninstallPreviousPackage">true</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment auf Android-Gerät</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deployment auf Android-Gerät</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.AndroidDeployConfiguration2</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
|
||||||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
|
||||||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
|
||||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
|
||||||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
|
||||||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
|
||||||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
|
||||||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
|
||||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
|
||||||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
|
||||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
|
||||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
|
||||||
<value type="int">0</value>
|
|
||||||
<value type="int">1</value>
|
|
||||||
<value type="int">2</value>
|
|
||||||
<value type="int">3</value>
|
|
||||||
<value type="int">4</value>
|
|
||||||
<value type="int">5</value>
|
|
||||||
<value type="int">6</value>
|
|
||||||
<value type="int">7</value>
|
|
||||||
<value type="int">8</value>
|
|
||||||
<value type="int">9</value>
|
|
||||||
<value type="int">10</value>
|
|
||||||
<value type="int">11</value>
|
|
||||||
<value type="int">12</value>
|
|
||||||
<value type="int">13</value>
|
|
||||||
<value type="int">14</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">friendiqa</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.AndroidRunConfiguration:/home/pankraz/ownCloud/clientsync/Friendiqa/v0.001/source-android/friendiqa.pro</value>
|
|
||||||
<value type="QString" key="QMakeProjectManager.QmakeAndroidRunConfiguration.ProFile">friendiqa.pro</value>
|
|
||||||
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
|
||||||
<value type="int">1</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
|
||||||
<value type="int">18</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>Version</variable>
|
|
||||||
<value type="int">18</value>
|
|
||||||
</data>
|
|
||||||
</qtcreator>
|
|
Binary file not shown.
|
@ -0,0 +1,56 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<manifest package="org.qtproject.friendiqa" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="0.001" android:versionCode="1" android:installLocation="auto">
|
||||||
|
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Friendiqa" android:icon="@drawable/icon">
|
||||||
|
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="Friendiqa" android:screenOrientation="unspecified" android:launchMode="singleTop">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
</intent-filter>
|
||||||
|
<meta-data android:name="android.app.lib_name" android:value="friendiqa"/>
|
||||||
|
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
|
||||||
|
<meta-data android:name="android.app.repository" android:value="default"/>
|
||||||
|
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
|
||||||
|
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
|
||||||
|
<!-- Deploy Qt libs as part of package -->
|
||||||
|
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
|
||||||
|
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
|
||||||
|
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
|
||||||
|
<!-- Run with local libs -->
|
||||||
|
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
|
||||||
|
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
|
||||||
|
<meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
|
||||||
|
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
|
||||||
|
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
|
||||||
|
<!-- Messages maps -->
|
||||||
|
<meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
|
||||||
|
<meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
|
||||||
|
<meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
|
||||||
|
<!-- Messages maps -->
|
||||||
|
|
||||||
|
<!-- Splash screen -->
|
||||||
|
<!--
|
||||||
|
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/>
|
||||||
|
-->
|
||||||
|
<!-- Splash screen -->
|
||||||
|
|
||||||
|
<!-- Background running -->
|
||||||
|
<!-- Warning: changing this value to true may cause unexpected crashes if the
|
||||||
|
application still try to draw after
|
||||||
|
"applicationStateChanged(Qt::ApplicationSuspended)"
|
||||||
|
signal is sent! -->
|
||||||
|
<meta-data android:name="android.app.background_running" android:value="false"/>
|
||||||
|
<!-- Background running -->
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="22"/>
|
||||||
|
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
|
||||||
|
|
||||||
|
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
|
||||||
|
Remove the comment if you do not require these default permissions. -->
|
||||||
|
<!-- %%INSERT_PERMISSIONS -->
|
||||||
|
|
||||||
|
<!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
|
||||||
|
Remove the comment if you do not require these default features. -->
|
||||||
|
<!-- %%INSERT_FEATURES -->
|
||||||
|
|
||||||
|
</manifest>
|
|
@ -0,0 +1,57 @@
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:1.1.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
/*******************************************************
|
||||||
|
* The following variables:
|
||||||
|
* - androidBuildToolsVersion,
|
||||||
|
* - androidCompileSdkVersion
|
||||||
|
* - qt5AndroidDir - holds the path to qt android files
|
||||||
|
* needed to build any Qt application
|
||||||
|
* on Android.
|
||||||
|
*
|
||||||
|
* are defined in gradle.properties file. This file is
|
||||||
|
* updated by QtCreator and androiddeployqt tools.
|
||||||
|
* Changing them manually might break the compilation!
|
||||||
|
*******************************************************/
|
||||||
|
|
||||||
|
compileSdkVersion androidCompileSdkVersion.toInteger()
|
||||||
|
|
||||||
|
buildToolsVersion androidBuildToolsVersion
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
manifest.srcFile 'AndroidManifest.xml'
|
||||||
|
java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
|
||||||
|
aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
|
||||||
|
res.srcDirs = [qt5AndroidDir + '/res', 'res']
|
||||||
|
resources.srcDirs = ['src']
|
||||||
|
renderscript.srcDirs = ['src']
|
||||||
|
assets.srcDirs = ['assets']
|
||||||
|
jniLibs.srcDirs = ['libs']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lintOptions {
|
||||||
|
abortOnError false
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
## This file is automatically generated by QtCreator.
|
||||||
|
#
|
||||||
|
# This file must *NOT* be checked into Version Control Systems,
|
||||||
|
# as it contains information specific to your local configuration.
|
||||||
|
|
||||||
|
androidBuildToolsVersion=23.0.2
|
||||||
|
androidCompileSdkVersion=18
|
||||||
|
buildDir=.build
|
||||||
|
qt5AndroidDir=/home/pankraz/bin/Qt5.5.1/5.5/android_armv7/src/android/java
|
Binary file not shown.
6
v0.002/Develop/source-android/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
v0.002/Develop/source-android/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#Wed Apr 10 15:27:10 PDT 2013
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip
|
|
@ -0,0 +1,164 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn ( ) {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die ( ) {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||||
|
if $cygwin ; then
|
||||||
|
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >&-
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >&-
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
|
function splitJvmOpts() {
|
||||||
|
JVM_OPTS=("$@")
|
||||||
|
}
|
||||||
|
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||||
|
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
|
@ -0,0 +1,90 @@
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windowz variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
goto execute
|
||||||
|
|
||||||
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
|
set CMD_LINE_ARGS=%$
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
|
@ -0,0 +1,6 @@
|
||||||
|
## This file is automatically generated by QtCreator.
|
||||||
|
#
|
||||||
|
# This file must *NOT* be checked into Version Control Systems,
|
||||||
|
# as it contains information specific to your local configuration.
|
||||||
|
|
||||||
|
sdk.dir=/opt/android-sdk
|
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<resources>
|
||||||
|
<array name="qt_sources">
|
||||||
|
<item>https://download.qt-project.org/ministro/android/qt5/qt-5.4</item>
|
||||||
|
</array>
|
||||||
|
|
||||||
|
<!-- The following is handled automatically by the deployment tool. It should
|
||||||
|
not be edited manually. -->
|
||||||
|
|
||||||
|
<array name="bundled_libs">
|
||||||
|
<!-- %%INSERT_EXTRA_LIBS%% -->
|
||||||
|
</array>
|
||||||
|
|
||||||
|
<array name="qt_libs">
|
||||||
|
<!-- %%INSERT_QT_LIBS%% -->
|
||||||
|
</array>
|
||||||
|
|
||||||
|
<array name="bundled_in_lib">
|
||||||
|
<!-- %%INSERT_BUNDLED_IN_LIB%% -->
|
||||||
|
</array>
|
||||||
|
<array name="bundled_in_assets">
|
||||||
|
<!-- %%INSERT_BUNDLED_IN_ASSETS%% -->
|
||||||
|
</array>
|
||||||
|
|
||||||
|
</resources>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>js/layout.js</file>
|
||||||
|
<file>js/photoworker.js</file>
|
||||||
|
<file>js/service.js</file>
|
||||||
|
<file>qml/FriendComponent.qml</file>
|
||||||
|
<file>qml/MessageSend.qml</file>
|
||||||
|
<file>qml/Newsitem.qml</file>
|
||||||
|
<file>qml/PhotoComponent.qml</file>
|
||||||
|
<file>qml/PhotogroupComponent.qml</file>
|
||||||
|
<file>qml/PhotoPlaceholder.qml</file>
|
||||||
|
<file>qml/friendiqa.qml</file>
|
||||||
|
<file>qml/PhotoTab.qml</file>
|
||||||
|
<file>qml/ConfigTab.qml</file>
|
||||||
|
<file>qml/FriendsTab.qml</file>
|
||||||
|
<file>qml/NewsTab.qml</file>
|
||||||
|
<file>js/news.js</file>
|
||||||
|
<file>js/newsworker.js</file>
|
||||||
|
<file>js/helper.js</file>
|
||||||
|
<file>images/defaultcontact.jpg</file>
|
||||||
|
<file>qml/InfoBox.qml</file>
|
||||||
|
<file>qml/GroupComponent.qml</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
|
@ -0,0 +1,49 @@
|
||||||
|
#include "filesystem.h"
|
||||||
|
|
||||||
|
FILESYSTEM *FILESYSTEM::instance()
|
||||||
|
{
|
||||||
|
static FILESYSTEM filesystem;
|
||||||
|
return &filesystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILESYSTEM::FILESYSTEM(QObject *parent) : QObject(parent){}
|
||||||
|
|
||||||
|
void FILESYSTEM::setDirectory(QString Directory)
|
||||||
|
{
|
||||||
|
if (Directory!=m_Directory) {
|
||||||
|
m_Directory = Directory;
|
||||||
|
emit directoryChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FILESYSTEM::Directory() const
|
||||||
|
{
|
||||||
|
return m_Directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FILESYSTEM::makeDir(QString name)
|
||||||
|
{
|
||||||
|
QDir dir(m_Directory);
|
||||||
|
if (dir.mkdir(name)){
|
||||||
|
emit success(name);
|
||||||
|
}
|
||||||
|
else {emit error(name,1);}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FILESYSTEM::rmDir(QString name)
|
||||||
|
{
|
||||||
|
QDir dir(m_Directory);
|
||||||
|
if (dir.rmdir(name)){
|
||||||
|
emit success(name);
|
||||||
|
}
|
||||||
|
else {emit error(name,1);}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FILESYSTEM::rmFile(QString name)
|
||||||
|
{
|
||||||
|
QDir dir(m_Directory);
|
||||||
|
if(dir.remove(name)){
|
||||||
|
emit success(name);
|
||||||
|
}
|
||||||
|
else {emit error(name,1);}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
#ifndef FILESYSTEM_H
|
||||||
|
#define FILESYSTEM_H
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class FILESYSTEM : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString Directory READ Directory WRITE setDirectory NOTIFY directoryChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
static FILESYSTEM *instance();
|
||||||
|
explicit FILESYSTEM(QObject *parent = 0);
|
||||||
|
void setDirectory(QString Directory);
|
||||||
|
QString Directory() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void directoryChanged();
|
||||||
|
void success(QString data);
|
||||||
|
void error(QString data, int code);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
//void setDirectory(QString Directory);
|
||||||
|
void makeDir(QString name);
|
||||||
|
void rmDir(QString name);
|
||||||
|
void rmFile(QString name);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
//void onReplyError(QNetworkReply::NetworkError code);
|
||||||
|
// void onReplySuccess();
|
||||||
|
//void onReadyRead();
|
||||||
|
// void onSSLError(const QList<QSslError> &errors);
|
||||||
|
|
||||||
|
private:
|
||||||
|
//QByteArray buffer;
|
||||||
|
QString m_Directory;
|
||||||
|
//QString m_login;
|
||||||
|
//QHash<QString, QString> params;
|
||||||
|
//QHash<QString, QString> files;
|
||||||
|
|
||||||
|
//QNetworkAccessManager manager;
|
||||||
|
//QNetworkRequest request;
|
||||||
|
//QNetworkReply *reply;
|
||||||
|
|
||||||
|
//QString bufferToString();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FILSYSTEM_H
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QtQml/QQmlEngine>
|
||||||
|
#include <QtQuick>
|
||||||
|
#include "xhr.h"
|
||||||
|
#include "filesystem.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
QQuickView view;
|
||||||
|
|
||||||
|
|
||||||
|
XHR* xhr = XHR::instance();
|
||||||
|
view.rootContext()->setContextProperty("xhr", xhr);
|
||||||
|
FILESYSTEM* filesystem = FILESYSTEM::instance();
|
||||||
|
view.rootContext()->setContextProperty("filesystem", filesystem);
|
||||||
|
view.setSource(QUrl("qrc:/qml/friendiqa.qml"));
|
||||||
|
view.show();
|
||||||
|
view.connect(view.rootContext()->engine(), SIGNAL(quit()), &app, SLOT(quit()));
|
||||||
|
return app.exec();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
#include "uploadableimage.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <QBuffer>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
void UploadableImage::setSource(const QString &a) {
|
||||||
|
if (a != m_source) {
|
||||||
|
m_source = a;
|
||||||
|
//m_base64 = "";
|
||||||
|
m_mimetype = "";
|
||||||
|
m_filename = "";
|
||||||
|
|
||||||
|
qDebug() << "UploadableImage::setSource : " << m_source;
|
||||||
|
|
||||||
|
if (m_source=="") {
|
||||||
|
emit sourceChanged();
|
||||||
|
//emit base64Changed();
|
||||||
|
emit mimetypeChanged();
|
||||||
|
emit filenameChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage fullimage = QImage(QUrl(m_source).toLocalFile());
|
||||||
|
if (fullimage.width() > 800 || fullimage.height() > 800) {
|
||||||
|
if (fullimage.width() > fullimage.height()) {
|
||||||
|
m_image = fullimage.scaledToWidth(800);
|
||||||
|
} else {
|
||||||
|
m_image = fullimage.scaledToHeight(800);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_image = fullimage;
|
||||||
|
}
|
||||||
|
qDebug() << "UploadableImage::setSource : " << m_image.width() << "x" << m_image.height();
|
||||||
|
emit sourceChanged();
|
||||||
|
|
||||||
|
QFileInfo fi(m_source);
|
||||||
|
|
||||||
|
m_filename = fi.fileName();
|
||||||
|
emit filenameChanged();
|
||||||
|
|
||||||
|
QString filetype = fi.suffix().toUpper();
|
||||||
|
if (filetype!="PNG" && filetype!="JPG") {
|
||||||
|
filetype = "JPG";
|
||||||
|
}
|
||||||
|
qDebug() << "UploadableImage::setSource : " << "Saving as " << filetype;
|
||||||
|
|
||||||
|
m_mimetype = "image/"+filetype.toLower();
|
||||||
|
emit mimetypeChanged();
|
||||||
|
|
||||||
|
/*
|
||||||
|
QByteArray byteArray;
|
||||||
|
QBuffer buffer(&byteArray);
|
||||||
|
m_image.save(&buffer, filetype.toLatin1().constData());
|
||||||
|
QString b64 = QString::fromLatin1(byteArray.toBase64().data());
|
||||||
|
|
||||||
|
for(int k=0; k<b64.length(); k+=76) {
|
||||||
|
m_base64 += b64.mid(k,76) + "\n";
|
||||||
|
}
|
||||||
|
m_base64 = m_base64.trimmed();
|
||||||
|
|
||||||
|
emit base64Changed();
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UploadableImage::source() const {
|
||||||
|
return m_source;
|
||||||
|
}
|
||||||
|
|
||||||
|
//QString UploadableImage::base64() const {
|
||||||
|
// return m_base64;
|
||||||
|
//}
|
||||||
|
|
||||||
|
QString UploadableImage::filename() const {
|
||||||
|
return m_filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UploadableImage::mimetype() const {
|
||||||
|
return m_mimetype;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray UploadableImage::bytes() {
|
||||||
|
QByteArray byteArray;
|
||||||
|
QBuffer buffer(&byteArray);
|
||||||
|
m_image.save(&buffer, "PNG");
|
||||||
|
return byteArray;
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef UPLOADABLEIMAGE_H
|
||||||
|
#define UPLOADABLEIMAGE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QQuickItem>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
class UploadableImage : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged)
|
||||||
|
//Q_PROPERTY(QString base64 READ base64 NOTIFY base64Changed)
|
||||||
|
Q_PROPERTY(QString filename READ filename NOTIFY filenameChanged)
|
||||||
|
Q_PROPERTY(QString mimetype READ mimetype NOTIFY mimetypeChanged)
|
||||||
|
Q_PROPERTY(QByteArray bytes READ bytes)
|
||||||
|
|
||||||
|
public:
|
||||||
|
void setSource(const QString &a);
|
||||||
|
QString source() const;
|
||||||
|
|
||||||
|
//QString base64() const;
|
||||||
|
QString filename() const;
|
||||||
|
QString mimetype() const;
|
||||||
|
|
||||||
|
QByteArray bytes();
|
||||||
|
signals:
|
||||||
|
void sourceChanged();
|
||||||
|
//void base64Changed();
|
||||||
|
void filenameChanged();
|
||||||
|
void mimetypeChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_source;
|
||||||
|
QImage m_image;
|
||||||
|
//QString m_base64;
|
||||||
|
QString m_filename;
|
||||||
|
QString m_mimetype;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // UPLOADABLEIMAGE_H
|
|
@ -0,0 +1,168 @@
|
||||||
|
#include "xhr.h"
|
||||||
|
|
||||||
|
#include <QHttpPart>
|
||||||
|
#include <QTextCodec>
|
||||||
|
#include <QUrlQuery>
|
||||||
|
|
||||||
|
#include "uploadableimage.h"
|
||||||
|
|
||||||
|
XHR *XHR::instance()
|
||||||
|
{
|
||||||
|
static XHR xhr;
|
||||||
|
return &xhr;
|
||||||
|
}
|
||||||
|
|
||||||
|
XHR::XHR(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
request.setSslConfiguration(QSslConfiguration::defaultConfiguration());
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::setUrl(QString url)
|
||||||
|
{
|
||||||
|
if (url!=m_url) {
|
||||||
|
m_url = url;
|
||||||
|
emit urlChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::setLogin(QString login)
|
||||||
|
{
|
||||||
|
if (login!=m_login) {
|
||||||
|
m_login = login;
|
||||||
|
emit loginChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString XHR::url() const
|
||||||
|
{
|
||||||
|
return m_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XHR::login() const
|
||||||
|
{
|
||||||
|
return m_login;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::setParam(QString name, QString value)
|
||||||
|
{
|
||||||
|
params.insert(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::setImageFileParam(QString name, QString url)
|
||||||
|
{
|
||||||
|
files.insert(name, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::clearParams()
|
||||||
|
{
|
||||||
|
files.clear();
|
||||||
|
params.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::get()
|
||||||
|
{
|
||||||
|
QUrlQuery query;
|
||||||
|
|
||||||
|
QHashIterator<QString, QString> i(params);
|
||||||
|
while(i.hasNext()) {
|
||||||
|
i.next();
|
||||||
|
query.addQueryItem(i.key(), i.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl requrl(m_url);
|
||||||
|
requrl.setQuery(query);
|
||||||
|
|
||||||
|
QByteArray loginData = m_login.toLocal8Bit().toBase64();
|
||||||
|
QString headerData = "Basic " + loginData;
|
||||||
|
request.setRawHeader("Authorization", headerData.toLocal8Bit());
|
||||||
|
|
||||||
|
|
||||||
|
request.setUrl(requrl);
|
||||||
|
reply = manager.get(request);
|
||||||
|
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &XHR::onReplySuccess);
|
||||||
|
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onReplyError(QNetworkReply::NetworkError)));
|
||||||
|
connect(reply, &QNetworkReply::readyRead, this, &XHR::onReadyRead);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::post()
|
||||||
|
{
|
||||||
|
qDebug() << "start post to " << m_url;
|
||||||
|
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
|
||||||
|
|
||||||
|
QHashIterator<QString, QString> iparams(params);
|
||||||
|
while(iparams.hasNext()) {
|
||||||
|
iparams.next();
|
||||||
|
qDebug() << "\t add param " << iparams.key() << " : " << iparams.value();
|
||||||
|
QHttpPart textPart;
|
||||||
|
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"" + iparams.key() + "\""));
|
||||||
|
|
||||||
|
|
||||||
|
textPart.setBody(iparams.value().toUtf8());
|
||||||
|
multiPart->append(textPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
UploadableImage uimg;
|
||||||
|
QHashIterator<QString, QString> ifiles(files);
|
||||||
|
while(ifiles.hasNext()) {
|
||||||
|
ifiles.next();
|
||||||
|
|
||||||
|
uimg.setSource(ifiles.value());
|
||||||
|
qDebug() << "\t image: " << uimg.mimetype() << ", " << ifiles.key();
|
||||||
|
|
||||||
|
QHttpPart imagePart;
|
||||||
|
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(uimg.mimetype()));
|
||||||
|
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"" + ifiles.key() + "\"; filename=\""+uimg.filename()+"\""));
|
||||||
|
imagePart.setBody(uimg.bytes());
|
||||||
|
multiPart->append(imagePart);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray loginData = m_login.toLocal8Bit().toBase64();
|
||||||
|
QString headerData = "Basic " + loginData;
|
||||||
|
request.setRawHeader(QByteArray("Authorization"), headerData.toLocal8Bit());
|
||||||
|
|
||||||
|
request.setUrl(m_url);
|
||||||
|
reply = manager.post(request, multiPart);
|
||||||
|
qDebug() << "\t request sent";
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &XHR::onReplySuccess);
|
||||||
|
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onReplyError(QNetworkReply::NetworkError)));
|
||||||
|
connect(reply, &QNetworkReply::readyRead, this, &XHR::onReadyRead);
|
||||||
|
connect(reply, &QNetworkReply::sslErrors, this, &XHR::onSSLError);
|
||||||
|
qDebug() << "\t reply signals connected";
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::onReplyError(QNetworkReply::NetworkError code)
|
||||||
|
{
|
||||||
|
qDebug() << code;
|
||||||
|
emit this->error( bufferToString(), (int) code);
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::onReplySuccess()
|
||||||
|
{
|
||||||
|
qDebug() << "!";
|
||||||
|
emit this->success( bufferToString() );
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::onReadyRead()
|
||||||
|
{
|
||||||
|
qDebug() << ".";
|
||||||
|
buffer += reply->readAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::onSSLError(const QList<QSslError> &errors)
|
||||||
|
{
|
||||||
|
qDebug() << "XHR::onSSLError :" ;
|
||||||
|
QListIterator<QSslError> ierrs(errors);
|
||||||
|
while(ierrs.hasNext()) {
|
||||||
|
qDebug() << "\t" << ierrs.next().errorString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XHR::bufferToString()
|
||||||
|
{
|
||||||
|
return QTextCodec::codecForName("utf-8")->toUnicode(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
#ifndef XHR_H
|
||||||
|
#define XHR_H
|
||||||
|
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class XHR : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged)
|
||||||
|
Q_PROPERTY(QString login READ login WRITE setLogin NOTIFY loginChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
static XHR *instance();
|
||||||
|
|
||||||
|
explicit XHR(QObject *parent = 0);
|
||||||
|
|
||||||
|
void setUrl(QString url);
|
||||||
|
// void setLogin(QString login);
|
||||||
|
|
||||||
|
QString url() const;
|
||||||
|
QString login() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void urlChanged();
|
||||||
|
void loginChanged();
|
||||||
|
void success(QString data);
|
||||||
|
void error(QString data, int code);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setLogin(QString login);
|
||||||
|
void setParam(QString name, QString value);
|
||||||
|
void setImageFileParam(QString name, QString url);
|
||||||
|
void clearParams();
|
||||||
|
void post();
|
||||||
|
void get();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onReplyError(QNetworkReply::NetworkError code);
|
||||||
|
void onReplySuccess();
|
||||||
|
void onReadyRead();
|
||||||
|
void onSSLError(const QList<QSslError> &errors);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QByteArray buffer;
|
||||||
|
QString m_url;
|
||||||
|
QString m_login;
|
||||||
|
QHash<QString, QString> params;
|
||||||
|
QHash<QString, QString> files;
|
||||||
|
|
||||||
|
QNetworkAccessManager manager;
|
||||||
|
QNetworkRequest request;
|
||||||
|
QNetworkReply *reply;
|
||||||
|
|
||||||
|
QString bufferToString();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // XHR_H
|
|
@ -0,0 +1,40 @@
|
||||||
|
# NOTICE:
|
||||||
|
#
|
||||||
|
# Application name defined in TARGET has a corresponding QML filename.
|
||||||
|
# If name defined in TARGET is changed, the following needs to be done
|
||||||
|
# to match new name:
|
||||||
|
# - corresponding QML filename must be changed
|
||||||
|
# - desktop icon filename must be changed
|
||||||
|
# - desktop filename must be changed
|
||||||
|
# - icon definition filename in desktop file must be changed
|
||||||
|
# - translation filenames have to be changed
|
||||||
|
|
||||||
|
# The name of your application
|
||||||
|
TARGET = friendiqa
|
||||||
|
CONFIG += debug
|
||||||
|
QT += qml quick gui widgets
|
||||||
|
|
||||||
|
SOURCES += common/friendiqa.cpp \
|
||||||
|
common/uploadableimage.cpp \
|
||||||
|
common/xhr.cpp \
|
||||||
|
common/filesystem.cpp
|
||||||
|
|
||||||
|
RESOURCES = application.qrc
|
||||||
|
|
||||||
|
OTHER_FILES += qml/friendiqa.qml \
|
||||||
|
translations/*.ts \
|
||||||
|
qml/*.qml
|
||||||
|
js/*.js
|
||||||
|
|
||||||
|
# German translation is enabled as an example. If you aren't
|
||||||
|
# planning to localize your app, remember to comment out the
|
||||||
|
# following TRANSLATIONS line. And also do not forget to
|
||||||
|
# modify the localized app name in the the .desktop file.
|
||||||
|
TRANSLATIONS += translations/friendiqa-de.ts
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
common/uploadableimage.h \
|
||||||
|
common/xhr.h \
|
||||||
|
common/filesystem.h
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,12 @@
|
||||||
|
WorkerScript.onMessage = function(msg) {
|
||||||
|
msg.model.clear();
|
||||||
|
for (var j=0;j<msg.albums.length;j++){
|
||||||
|
if (msg.albums[j]) {
|
||||||
|
var albumobject=msg.albums[j];
|
||||||
|
var data=({"albumobject": albumobject,"foreignPicture": msg.foreignPicture})}
|
||||||
|
// print("Albums:"+j+msg.albums.length+JSON.stringify(data));
|
||||||
|
msg.model.append(data);}
|
||||||
|
if (j==msg.albums.length){
|
||||||
|
msg.model.sync()
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
.pragma library
|
||||||
|
.import QtQuick.LocalStorage 2.0 as Sql
|
||||||
|
|
||||||
|
function friendicaRequest(login,api,rootwindow,callback) {
|
||||||
|
var xhrequest= new XMLHttpRequest();
|
||||||
|
xhrequest.onreadystatechange = function() {
|
||||||
|
if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
|
||||||
|
} else if(xhrequest.readyState === XMLHttpRequest.DONE) {
|
||||||
|
try{ if (xhrequest.responseText!=""){
|
||||||
|
callback(xhrequest.responseText)
|
||||||
|
}else{
|
||||||
|
showMessage("Error",api+" NO RESPONSE",rootwindow)
|
||||||
|
callback(xhrequest.responseText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e){
|
||||||
|
showMessage("Error", api+" "+e,rootwindow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhrequest.open("GET", login.server+api,true,login.username,Qt.atob(login.password));
|
||||||
|
xhrequest.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function friendicaPostRequest(login,api,rootwindow,callback) {
|
||||||
|
var xhrequest= new XMLHttpRequest();
|
||||||
|
xhrequest.onreadystatechange = function() {
|
||||||
|
if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
|
||||||
|
} else if(xhrequest.readyState === XMLHttpRequest.DONE) {
|
||||||
|
try{ if (xhrequest.responseText!=""){
|
||||||
|
callback(xhrequest.responseText)
|
||||||
|
}else{
|
||||||
|
showMessage("Error",api+" NO RESPONSE",rootwindow)
|
||||||
|
callback(xhrequest.responseText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e){
|
||||||
|
showMessage("Error", api+" "+e,rootwindow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhrequest.open("POST", login.server+api,true,login.username,Qt.atob(login.password));
|
||||||
|
xhrequest.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function friendicaWebRequest(url,rootwindow,callback) {
|
||||||
|
var xhrequest = new XMLHttpRequest();
|
||||||
|
xhrequest.onreadystatechange = function() {
|
||||||
|
if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
|
||||||
|
} else if(xhrequest.readyState === XMLHttpRequest.DONE) {
|
||||||
|
try{ callback(xhrequest.responseText);
|
||||||
|
}
|
||||||
|
catch (e){
|
||||||
|
showMessage("Error",url+" "+e, rootwindow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhrequest.open("GET", url,true);
|
||||||
|
xhrequest.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function readData(database,table,username,callback,filter,filtervalue) { // reads and applies data from DB
|
||||||
|
if (filter){
|
||||||
|
var where = " AND "+ filter +" = '" + filtervalue+"'";
|
||||||
|
} else { var where="";}
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
if(!db) { return; }
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
// print('select * from '+table'+where username= "'+username+'"'+'where);
|
||||||
|
var rsArray=[];
|
||||||
|
var rs = tx.executeSql('select * from '+table+' where username= "'+username+'"'+where);
|
||||||
|
for(var i = 0; i < rs.rows.length; i++) {
|
||||||
|
rsArray.push(rs.rows.item(i))
|
||||||
|
}
|
||||||
|
callback(rsArray);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function readField(field,database,table, username, callback,filter,filtervalue) { // reads and applies data from DB
|
||||||
|
if (filter){
|
||||||
|
var where = " AND "+ filter +" = '" + filtervalue+"'";
|
||||||
|
} else { var where="";}
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
if(!db) { return; }
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
// print('... read from database ' + field)
|
||||||
|
var rsArray=[];
|
||||||
|
print('select DISTINCT '+field+' from '+table+' WHERE username="'+username+'"'+where+' ORDER BY '+field+' ASC');
|
||||||
|
var rs = tx.executeSql('select DISTINCT '+field+' from '+table+' WHERE username="'+username+'"'+where+' ORDER BY '+field+' ASC');
|
||||||
|
for(var i = 0; i < rs.rows.length; i++) {
|
||||||
|
rsArray.push(rs.rows.item(i)[field])
|
||||||
|
}
|
||||||
|
callback(rsArray);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showMessage(header,message,rootwindow){
|
||||||
|
var messageString='import QtQuick 2.0; import QtQuick.Dialogs 1.2; MessageDialog{ visible: true; title:"'+header+'";standardButtons: StandardButton.Ok; text:" '+message+'"}';
|
||||||
|
var messageObject=Qt.createQmlObject(messageString,rootwindow,"messageOutput");
|
||||||
|
}
|
||||||
|
|
||||||
|
function inArray(list, prop, val) {
|
||||||
|
if (list.length > 0 ) {
|
||||||
|
for (var i in list) { if (list[i][prop] === val) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} return -1;
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
function showFriends(db) {
|
||||||
|
Service.readActiveConfig(db,function(login){
|
||||||
|
Service.requestFriends(login.url,login.user,login.password,displayFriends);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function displayFriends(obj){
|
||||||
|
for (var i=0; i<obj.length; i++){
|
||||||
|
print(obj[i]);
|
||||||
|
if (obj[i]) {friendsModel.append({"friendName": obj[i]});
|
||||||
|
};
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
function ensureVisibility(c,f)
|
||||||
|
{
|
||||||
|
if (f.contentX >= c.x)
|
||||||
|
f.contentX = c.x;
|
||||||
|
else if (f.contentX+f.width <= c.x+c.width)
|
||||||
|
f.contentX = c.x+c.width-f.width;
|
||||||
|
if (f.contentY >= c.y)
|
||||||
|
f.contentY = c.y;
|
||||||
|
else if (f.contentY+f.height <= c.y+c.height)
|
||||||
|
f.contentY = c.y+c.height-f.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createObject(objectQml,qmlParameters,parentitem,callback) {
|
||||||
|
var component = Qt.createComponent(objectQml);
|
||||||
|
if (component.status === Component.Ready || component.status === Component.Error)
|
||||||
|
finishCreation(component,qmlParameters,parentitem,callback);
|
||||||
|
else
|
||||||
|
component.statusChanged.connect(finishCreation(qmlParameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishCreation(component,qmlParameters,parentitem,callback) {
|
||||||
|
if (component.status === Component.Ready) {
|
||||||
|
var createdObject = component.createObject(parentitem, qmlParameters);
|
||||||
|
if (createdObject === null)
|
||||||
|
print("Error creating image"); }
|
||||||
|
else if (component.status === Component.Error)
|
||||||
|
print("Error loading component:"+component.errorString());
|
||||||
|
else {print("created")}
|
||||||
|
callback(createdObject);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,311 @@
|
||||||
|
.pragma library
|
||||||
|
.import QtQuick.LocalStorage 2.0 as Sql
|
||||||
|
.import "qrc:/js/helper.js" as Helperjs
|
||||||
|
|
||||||
|
function requestFriends(login,database,rootwindow,callback){
|
||||||
|
// return array of friends
|
||||||
|
Helperjs.friendicaRequest(login,"/api/statuses/friends", rootwindow,function (obj){
|
||||||
|
var friends=JSON.parse(obj);
|
||||||
|
for (var i=0;i<friends.length;i++){ friends[i].isFriend=1}
|
||||||
|
callback(friends)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function requestGroups(login,database,rootwindow,callback){
|
||||||
|
// retrieve, save and return groups, currently not implemented
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
Helperjs.friendicaRequest(login,"/api/friendica/group_show",rootwindow, function (obj){
|
||||||
|
var groups=JSON.parse(obj);
|
||||||
|
for (var i=0;i<groups.length;i++){
|
||||||
|
var memberarray=[]; for (var user in groups[i].user){memberarray.push(parseInt(groups[i].user[user].id))}
|
||||||
|
//print("Members: "+groups[i].user)
|
||||||
|
//updateGroupInDB(login,database,groups[i])
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
var result = tx.executeSql('SELECT * from groups where username="'+login.username+'" AND gid = "'+groups[i].gid+'"'); // check for group id
|
||||||
|
if(result.rows.length === 1) {// use update
|
||||||
|
print(groups[i].gid +' exists, update it')
|
||||||
|
result = tx.executeSql('UPDATE groups SET username="'+login.username+'", groupname="'+groups[i].name+'", members="'+JSON.stringify(memberarray)+'"');
|
||||||
|
} else {// use insert
|
||||||
|
result = tx.executeSql('INSERT INTO groups VALUES (?,?,?,?)', [login.username,groups[i].name,groups[i].gid,JSON.stringify(memberarray)])}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//Helperjs.readData(database,"groups",login.username,callback)
|
||||||
|
callback()
|
||||||
|
});}
|
||||||
|
|
||||||
|
function getFriendsTimeline(login,database,contacts,rootwindow,callback){// retrieve and return timeline since last news, return contacts which are not friends for update (friends can be updated in Friendstab)
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
var parameter = "";
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" ORDER BY status_id DESC LIMIT 1'); // check for last news id
|
||||||
|
try{parameter="&since_id="+result.rows.item(0).status_id;}catch(e){};})
|
||||||
|
var newContacts=[];
|
||||||
|
Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){
|
||||||
|
var news=JSON.parse(obj);
|
||||||
|
for (var i=0;i<news.length;i++){
|
||||||
|
if(contacts.indexOf(news[i].user.id)==-1 && !(inArray(newContacts,"id",news[i].user.id))){
|
||||||
|
news[i].user.isFriend=0;
|
||||||
|
newContacts.push(news[i].user);
|
||||||
|
}
|
||||||
|
if (news[i].friendica_activities.like.length>0){
|
||||||
|
print("Like Contact"+JSON.stringify(news[i].friendica_activities.like));
|
||||||
|
for (var j=0;j<news[i].friendica_activities.like.length;j++){
|
||||||
|
if(contacts.indexOf(news[i].friendica_activities.like[j].id)==-1 && !(inArray(newContacts,"id",news[i].friendica_activities.like[j].id))){
|
||||||
|
news[i].friendica_activities.like[j].isFriend=0;
|
||||||
|
newContacts.push(news[i].friendica_activities.like[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (news[i].friendica_activities.dislike.length>0){
|
||||||
|
print("DisLike Contact"+JSON.stringify(news[i].friendica_activities.dislike));
|
||||||
|
for (var k=0;j<news[k].friendica_activities.dislike.length;k++){
|
||||||
|
if(contacts.indexOf(news[i].friendica_activities.dislike[k].id)==-1 && !(inArray(newContacts,"id",news[i].friendica_activties.dislike[k].id))){
|
||||||
|
news[i].friendica_activities.dislike[k].isFriend=0;
|
||||||
|
newContacts.push(news[i].friendica_activities.dislike[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback(news,newContacts)
|
||||||
|
})}
|
||||||
|
|
||||||
|
function storeNews(login,database,news,rootwindow,callback){
|
||||||
|
// save news after contacts download, call next function
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
for (var i=0;i<news.length;i++){
|
||||||
|
print('store news data for ' + news[i].id+JSON.stringify(news[i].friendica_activities));
|
||||||
|
var ausdruck=news[i];
|
||||||
|
var likearray=[]; for (var user in news[i].friendica_activities.like){likearray.push(parseInt(news[i].friendica_activities.like[user].id))}
|
||||||
|
var dislikearray=[]; for (var user in news[i].friendica_activities.dislike){parseInt(news[i].friendica_activities.dislike[user].id)}
|
||||||
|
var attendyesarray=[]; for (var user in news[i].friendica_activities.attendyes){attendyesarray.push(parseInt(news[i].friendica_activities.attendyes[user].id))}
|
||||||
|
var attendnoarray=[]; for (var user in news[i].friendica_activities.attendno){attendnoarray.push(parseInt(news[i].friendica_activities.attendno[user].id))}
|
||||||
|
var attendmaybearray=[]; for (var user in news[i].friendica_activities.attendmaybe){attendmaybearray.push(parseInt(news[i].friendica_activities.attendmaybe[user].id))}
|
||||||
|
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
var result = tx.executeSql('SELECT * from news where status_id = "'+news[i].id+'"'); // check for news id
|
||||||
|
if(result.rows.length === 1) {// use update
|
||||||
|
print(news[i].id +' exists, update it')
|
||||||
|
result = tx.executeSql('UPDATE news SET username="'+login.username+'", messagetype=0, text="'+Qt.btoa(news[i].text)+'", created_at="'+Date.parse(cleanDate(news[i].created_at))+'", in_reply_to_status_id="'+news[i].in_reply_to_status_id+'", source="'+news[i].source+'", status_id="'+news[i].id+'", in_reply_to_user_id="'+news[i].in_reply_to_user_id+'", geo="'+news[i].geo+'", favorited="'+news[i].favorited+'", uid="'+news[i].user.id+'", statusnet_html="'+Qt.btoa(news[i].status_html)+'", statusnet_conversation_id="'+news[i].statusnet_conversation_id+'",like="'+JSON.stringify(likearray)+'", dislike="'+JSON.stringify(dislikearray)+'", attendyes="'+JSON.stringify(attendyesarray)+'",attendno="'+JSON.stringify(attendnoarray)+'",attendmaybe="'+JSON.stringify(attendmaybearray)+'" where status_id="'+news[i].status_id+'"');
|
||||||
|
} else {// use insert
|
||||||
|
result = tx.executeSql('INSERT INTO news (username,messagetype,text,created_at,in_reply_to_status_id,source,status_id,in_reply_to_user_id,geo,favorited,uid,statusnet_html,statusnet_conversation_id,like,dislike,attendyes,attendno,attendmaybe) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,0,Qt.btoa(news[i].text),Date.parse(cleanDate(news[i].created_at)), news[i].in_reply_to_status_id, news[i].source, news[i].id,news[i].in_reply_to_user_id,news[i].geo,news[i].favorited, news[i].user.id,Qt.btoa(news[i].statusnet_html),news[i].statusnet_conversation_id, JSON.stringify(likearray),JSON.stringify(dislikearray),JSON.stringify(attendyesarray),JSON.stringify(attendnoarray),JSON.stringify(attendmaybearray)])}})
|
||||||
|
}
|
||||||
|
getDirectMessage(login,database,rootwindow,callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDirectMessage(login,database,rootwindow,callback){
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
Helperjs.friendicaRequest(login,"/api/direct_messages/all",rootwindow, function (obj){
|
||||||
|
var messages=JSON.parse(obj);
|
||||||
|
for (var i=0;i<messages.length;i++){
|
||||||
|
// print('store message data for '+JSON.stringify(messages[i]));
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
var result = tx.executeSql('SELECT * from news where status_id = "'+messages[i].id+'"'); // check for news id
|
||||||
|
if(result.rows.length === 1) {// use update
|
||||||
|
print(messages[i].id +' exists, update it')
|
||||||
|
result = tx.executeSql('UPDATE news SET username="'+login.username+'", messagetype=1, text="'+Qt.btoa(messages[i].text)+'", created_at="'+Date.parse(cleanDate(messages[i].created_at))+'", source="Friendica", status_id="'+messages[i].id+'", uid="'+messages[i].sender.id+'", statusnet_html="'+Qt.btoa(messages[i].text)+'" where status_id="'+messages[i].status_id+'"');
|
||||||
|
} else {// use insert
|
||||||
|
result = tx.executeSql('INSERT INTO news (username,messagetype,text,created_at,source,status_id,uid,statusnet_html) VALUES (?,?,?,?,?,?,?,?)', [login.username,1,Qt.btoa(messages[i].text),Date.parse(cleanDate(messages[i].created_at)), "Friendica", messages[i].id, messages[i].sender.id,Qt.btoa(messages[i].text)])}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
getNotifications(login,database,rootwindow,callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNotifications(login,database,rootwindow,callback){
|
||||||
|
Helperjs.friendicaRequest(login,"/api/friendica/notifications", rootwindow,function (obj){
|
||||||
|
var messages=JSON.parse(obj);
|
||||||
|
for (var i=0;i<messages.length;i++){
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
//print('store message data for '+JSON.stringify(messages[i]));
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
var result = tx.executeSql('SELECT * from news where status_id = "'+messages[i].id+'"'); // check for news id
|
||||||
|
if(result.rows.length === 1) {// use update
|
||||||
|
print(messages[i].id +' exists, update it')
|
||||||
|
result = tx.executeSql('UPDATE news SET username="'+login.username+'", messagetype=2, text="'+Qt.btoa(messages[i].msg_html)+'", created_at="'+messages[i].timestamp+'", source="Friendica", status_id="'+messages[i].id+'", uid="'+messages[i].uid+'", statusnet_html="'+Qt.btoa(messages[i].msg_html)+'", statusnet_conversation_id="'+messages[i].parent+'" where status_id="'+messages[i].id+'"');
|
||||||
|
} else {// use insert
|
||||||
|
result = tx.executeSql('INSERT INTO news (username,messagetype,text,created_at,source,status_id, uid,statusnet_html,statusnet_conversation_id) VALUES (?,?,?,?,?,?,?,?,?)', [login.username,2,Qt.btoa(messages[i].msg_html),messages[i].timestamp,"Friendica", messages[i].id, messages[i].uid,Qt.btoa(messages[i].msg_html),messages[i].parent])}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
newsfromdb(database,login.username,callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
function newsfromdb(database,username,callback,contact,stop_time){
|
||||||
|
// return news before stop_time (used by More button), in brackets of 20 entries, or by specified contact
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
if (!stop_time){var stop="";
|
||||||
|
try{var rs = tx.executeSql('select created_at from news WHERE username="'+username+'" ORDER BY created_at DESC LIMIT 1');
|
||||||
|
stop="<="+rs.rows.item(0).created_at}catch(e){stop="<99999999999999"}}
|
||||||
|
else{var stop="<"+stop_time}
|
||||||
|
var contactfilter="";if(contact){contactfilter=" AND uid='"+contact+"'"}
|
||||||
|
var newsrs=tx.executeSql('select * from news WHERE username="'+username+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20');
|
||||||
|
var newsArray=[];
|
||||||
|
for(var i = 0; i < newsrs.rows.length; i++) {
|
||||||
|
newsArray.push(newsrs.rows.item(i));
|
||||||
|
Helperjs.readData(database,"contacts",username,function(userdata){
|
||||||
|
newsArray[i].user=userdata[0];
|
||||||
|
},"id",newsArray[i].uid);
|
||||||
|
if(newsArray[i].in_reply_to_user_id){
|
||||||
|
Helperjs.readData(database,"contacts",username,function(replytodata){
|
||||||
|
newsArray[i].reply_user=replytodata[0];
|
||||||
|
},"id",newsArray[i].in_reply_to_user_id);
|
||||||
|
}
|
||||||
|
if (newsArray[i].messagetype==0){
|
||||||
|
//userdata for likes
|
||||||
|
var likeArray=JSON.parse(newsArray[i].like);
|
||||||
|
var likeHelper=[];
|
||||||
|
for (var j=0;j<likeArray.length;j++){
|
||||||
|
Helperjs.readData(database,"contacts",username,function(userdata){
|
||||||
|
likeHelper[j]=userdata[0];
|
||||||
|
},"id",likeArray[j]);
|
||||||
|
}
|
||||||
|
newsArray[i].like=likeHelper;
|
||||||
|
//userdata for dislikes
|
||||||
|
var dislikeArray=JSON.parse(newsArray[i].dislike);
|
||||||
|
var dislikeHelper=[];
|
||||||
|
for (var k=0;k<dislikeArray.length;k++){
|
||||||
|
Helperjs.readData(database,"contacts",username,function(userdata){
|
||||||
|
dislikeHelper[j]=userdata[0];
|
||||||
|
},"id",dislikeArray[k]);
|
||||||
|
}
|
||||||
|
newsArray[i].dislike=dislikeHelper;
|
||||||
|
//userdata for attendyes
|
||||||
|
var attendyesArray=JSON.parse(newsArray[i].attendyes);
|
||||||
|
var attendyesHelper=[];
|
||||||
|
for (var l=0;l<attendyesArray.length;l++){
|
||||||
|
Helperjs.readData(database,"contacts",username,function(userdata){
|
||||||
|
attendyesHelper[j]=userdata[0];
|
||||||
|
},"id",attendyesArray[l]);
|
||||||
|
}
|
||||||
|
newsArray[i].attendyes=attendyesHelper;
|
||||||
|
//userdata for attendno
|
||||||
|
var attendnoArray=JSON.parse(newsArray[i].attendno);
|
||||||
|
var attendnoHelper=[];
|
||||||
|
for (var m=0;m<attendnoArray.length;m++){
|
||||||
|
Helperjs.readData(database,"contacts",username,function(userdata){
|
||||||
|
attendnoHelper[j]=userdata[0];
|
||||||
|
},"id",attendnoArray[m]);
|
||||||
|
}
|
||||||
|
newsArray[i].attendno=attendnoHelper;
|
||||||
|
|
||||||
|
//userdata for attendmaybe
|
||||||
|
var attendmaybeArray=JSON.parse(newsArray[i].attendmaybe);
|
||||||
|
var attendmaybeHelper=[];
|
||||||
|
for (var n=0;n<attendmaybeArray.length;n++){
|
||||||
|
Helperjs.readData(database,"contacts",username,function(userdata){
|
||||||
|
attendmaybeHelper[j]=userdata[0];
|
||||||
|
},"id",attendmaybeArray[l]);
|
||||||
|
}
|
||||||
|
newsArray[i].attendmaybe=attendmaybeHelper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback(newsArray)});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteNews(login,database,newsid,rootwindow,callback){
|
||||||
|
Helperjs.friendicaPostRequest(login,"/api/statuses/destroy?id="+newsid, rootwindow,function (obj){
|
||||||
|
print("Delete "+obj);
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
print('delete news data for ' + newsid);
|
||||||
|
db.transaction( function(tx) {var result = tx.executeSql('DELETE from news where status_id ='+newsid); // delete news id
|
||||||
|
Helperjs.showMessage("Delete",result,rootwindow)});
|
||||||
|
})}
|
||||||
|
|
||||||
|
function retweetNews(login,database,newsid,rootwindow,callback){
|
||||||
|
Helperjs.friendicaRequest(login,"/api/statuses/retweet?id="+newsid, rootwindow,function (obj){
|
||||||
|
var answer=JSON.parse(obj);
|
||||||
|
Helperjs.showMessage("Repost",answer,rootwindow);
|
||||||
|
})}
|
||||||
|
|
||||||
|
function favorite(login,favorite,newsid,rootwindow){
|
||||||
|
// toggle favorites
|
||||||
|
if(favorite){ Helperjs.friendicaPostRequest(login,"/api/favorites/create?id="+newsid, rootwindow,function (obj){
|
||||||
|
print("Favorite "+obj);
|
||||||
|
})}
|
||||||
|
else {Helperjs.friendicaPostRequest(login,"/api/favorites/destroy?id="+newsid, rootwindow,function (obj){
|
||||||
|
print("Favorite destroyed "+obj);
|
||||||
|
})}
|
||||||
|
}
|
||||||
|
|
||||||
|
function likerequest(login,database,toggle,verb,newsid,rootwindow){
|
||||||
|
Helperjs.friendicaPostRequest(login,"/api/friendica/activity/"+verb+"?id="+newsid, rootwindow,function (obj){
|
||||||
|
print("likereturn "+obj);
|
||||||
|
if (obj=='"ok"'){
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
db.transaction( function(tx) {var result = tx.executeSql('UPDATE news SET '+verb+'d ='+toggle+' where status_id ='+newsid);
|
||||||
|
})}})
|
||||||
|
}
|
||||||
|
|
||||||
|
function like(login,database,toggle,verb,newsid,rootwindow){
|
||||||
|
if(verb=="like"&& toggle==1){
|
||||||
|
likerequest(login,database,1,"like",newsid,rootwindow);
|
||||||
|
likerequest(login,database,0,"undislike",newsid,rootwindow);}
|
||||||
|
if(verb=="dislike"&& toggle==1){
|
||||||
|
likerequest(login,database,1,"dislike",newsid,rootwindow);
|
||||||
|
likerequest(login,database,0,"unlike",newsid,rootwindow);}
|
||||||
|
if(toggle==0){
|
||||||
|
likerequest(login,database,0,"un"+verb,newsid,rootwindow);}
|
||||||
|
}
|
||||||
|
|
||||||
|
function attend(login,database,attend,newsid,rootwindow,callback){
|
||||||
|
Helperjs.friendicaPostRequest(login,"/api/friendica/activity/attend"+attend+"?id="+newsid, rootwindow,function (obj){
|
||||||
|
var attendReturn=JSON.parse(obj);
|
||||||
|
// print("attend: "+obj);
|
||||||
|
//if (attendReturn=="OK")
|
||||||
|
{
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
db.transaction( function(tx) {var result = tx.executeSql('UPDATE news SET attend="+attend+" where status_id ='+newsid);
|
||||||
|
callback();
|
||||||
|
})}})}
|
||||||
|
|
||||||
|
function requestConversation(login,database,newsid,rootwindow,callback){
|
||||||
|
Helperjs.friendicaRequest(login,"/api/conversation/show?id="+newsid,rootwindow, function (obj){
|
||||||
|
print(obj+JSON.stringify(obj));
|
||||||
|
var news=JSON.parse(obj);
|
||||||
|
for (var i=0;i<news.length;i++){
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
print('store news data for ' + news[i].id);
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
var result = tx.executeSql('SELECT * from news where status_id = "'+news[i].id+'"'); // check for news id
|
||||||
|
if(result.rows.length === 1) {// use update
|
||||||
|
print(news[i].id +' exists, update it')
|
||||||
|
result = tx.executeSql('UPDATE news SET username="'+login.username+'", messagetype=0, text="'+Qt.btoa(news[i].text)+'", truncated="'+news[i].truncated+'", created_at="'+Date.parse(cleanDate(news[i].created_at))+'", in_reply_to_status_id="'+news[i].in_reply_to_status_id+'", source="'+news[i].source+'", status_id="'+news[i].id+'", in_reply_to_user_id="'+news[i].in_reply_to_user_id+'", geo="'+news[i].geo+'", favorited="'+news[i].favorited+'", uid="'+news[i].user.id+'", statusnet_html="'+Qt.btoa(news[i].status_html)+'", statusnet_conversation_id="'+news[i].statusnet_conversation_id+'", attachments="'+news[i].attachments+'" where status_id="'+news[i].status_id+'"');
|
||||||
|
} else {// use insert
|
||||||
|
result = tx.executeSql('INSERT INTO news VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,0,Qt.btoa(news[i].text),news[i].truncated,Date.parse(cleanDate(news[i].created_at)), news[i].in_reply_to_status_id, news[i].source, news[i].id,news[i].in_reply_to_user_id,news[i].geo,news[i].favorited, news[i].user.id,Qt.btoa(news[i].statusnet_html),news[i].statusnet_conversation_id, news[i].attachments,0,0,0]);
|
||||||
|
}});
|
||||||
|
if(news[i].user.following!=true){
|
||||||
|
updateContactInDB(login,database,rootwindow,news[i].user)}
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
);}
|
||||||
|
|
||||||
|
function conversationfromdb(database,user,conversationId,callback){
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
print('select * from news WHERE statusnet_conversation_id='+conversationId+' ORDER BY status_id DESC');
|
||||||
|
var newsrs=tx.executeSql('select * from news WHERE statusnet_conversation_id='+conversationId+' ORDER BY status_id DESC');
|
||||||
|
var newsArray=[];
|
||||||
|
for(var i = 0; i < newsrs.rows.length; i++) {
|
||||||
|
newsArray.push(newsrs.rows.item(i))
|
||||||
|
Helperjs.readData(database,"contacts",function(userdata){
|
||||||
|
newsArray[i].user=userdata[0];
|
||||||
|
},"id",newsArray[i].uid);
|
||||||
|
}
|
||||||
|
callback(newsArray);
|
||||||
|
});}
|
||||||
|
|
||||||
|
function inArray(list, prop, val) {
|
||||||
|
if (list.length > 0 ) {
|
||||||
|
for (var i in list) { if (list[i][prop] === val) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanDate(date){
|
||||||
|
var cleanedDate= date.slice(0,3)+", "+date.slice(8,11)+date.slice(4,7)+date.slice(25,30)+date.slice(10,25);
|
||||||
|
return cleanedDate
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
WorkerScript.onMessage = function(msg) {
|
||||||
|
if(msg.appendnews!==true){ msg.model.clear()};
|
||||||
|
for (var j=0;j<msg.news.length;j++){
|
||||||
|
if (msg.news[j]) {
|
||||||
|
var newsitemobject=msg.news[j];
|
||||||
|
var likeText="";var dislikeText="";var attendyesText="";var attendnoText="";var attendmaybeText="";
|
||||||
|
if (newsitemobject.messagetype==0){
|
||||||
|
if (msg.news[j].like.length>0){
|
||||||
|
if (msg.news[j].like.length==1){likeText= Qt.atob(msg.news[j].like[0].name)+" "+ qsTr("likes this.")}
|
||||||
|
else {likeText= msg.news[j].like.length+" "+ qsTr("like this.")}
|
||||||
|
}
|
||||||
|
if (msg.news[j].dislike.length>0){
|
||||||
|
if (msg.news[j].dislike.length==1){dislikeText= QT.atob(msg.news[j].dislike[0].name)+" "+ qsTr("doesn't like this.")}
|
||||||
|
else {dislikeText= msg.news[j].dislike.length+" "+ qsTr("don't like this.")}
|
||||||
|
}
|
||||||
|
if (msg.news[j].attendyes.length>0){
|
||||||
|
if (msg.news[j].attendyes.length==1){attendyesText= Qt.atob(msg.news[j].attendyes[0].name)+" "+ qsTr("will attend.")}
|
||||||
|
else {attendyesText= msg.news[j].attendyes.length+" "+ qsTr("persons will attend.")}
|
||||||
|
}
|
||||||
|
if (msg.news[j].attendno.length>0){
|
||||||
|
if (msg.news[j].attendno.length==1){attendnoText= Qt.atob(msg.news[j].attendno[0].name)+" "+ qsTr("will not attend.")}
|
||||||
|
else {attendnoText= msg.news[j].attendno.length+" "+ qsTr("persons will not attend.")}
|
||||||
|
}
|
||||||
|
if (msg.news[j].attendmaybe.length>0){
|
||||||
|
if (msg.news[j].attendmaybe.length==1){attendmaybeText= Qt.atob(msg.news[j].attendmaybe[0].name)+" "+ qsTr("may attend.")}
|
||||||
|
else {attendmaybeText= msg.news[j].attendmaybe.length+" "+ qsTr("persons may attend.")}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var friendica_activities={likeText:likeText,dislikeText:dislikeText,attendyesText:attendyesText,attendnoText:attendnoText,attendmaybeText:attendmaybeText}
|
||||||
|
var seconds=(msg.currentTime-newsitemobject.created_at)/1000;
|
||||||
|
var timestring="";
|
||||||
|
if (seconds<60) {timestring=seconds+" "+qsTr("seconds") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<90){timestring=Math.round(seconds/60)+" "+qsTr("minute") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<3600){timestring=Math.round(seconds/60)+" "+qsTr("minutes") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<5400){timestring=Math.round(seconds/3600)+" "+qsTr("hour") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<86400){timestring=Math.round(seconds/3600)+" "+qsTr("hours") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<129600){timestring=Math.round(seconds/86400)+" "+qsTr("day") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<3888000){timestring=Math.round(seconds/86400)+" "+qsTr("days") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<5832000){timestring=Math.round(seconds/3888000)+" "+qsTr("month") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<69984000){timestring=Math.round(seconds/3888000)+" "+qsTr("months") +" "+qsTr("ago");}
|
||||||
|
else {timestring=Math.round(seconds/69984000)+" "+qsTr("years") +" "+qsTr("ago");}
|
||||||
|
var data=({"newsitemobject": newsitemobject,"dateDiff":timestring,"friendica_activities":friendica_activities})}
|
||||||
|
// print("News:"+j+msg.news.length+JSON.stringify(data));
|
||||||
|
msg.model.append(data);}
|
||||||
|
if (j==msg.news.length){
|
||||||
|
msg.model.sync()
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
WorkerScript.onMessage = function(msg) {
|
||||||
|
if (msg.firstalbum==0){msg.model.clear();}
|
||||||
|
var limit=0; if (msg.albums.length-msg.firstalbum<20){limit=msg.albums.length} else{limit=msg.firstalbum+20}
|
||||||
|
for (var j=msg.firstalbum;j<limit;j++){
|
||||||
|
if (msg.albums[msg.firstalbum]) {
|
||||||
|
// print("album"+msg.albums[j].name);
|
||||||
|
if(msg.foreignPicture){
|
||||||
|
var albumname=msg.albums[j].name.trim();var albumlink=msg.albums[j].link
|
||||||
|
}else{
|
||||||
|
var albumname=msg.albums[j].toString();var albumlink=""}
|
||||||
|
msg.model.append({"albumlink":albumlink,"foreignPicture":msg.foreignPicture,"albumname":albumname});
|
||||||
|
msg.model.sync()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,222 @@
|
||||||
|
//.pragma library
|
||||||
|
.import QtQuick.LocalStorage 2.0 as Sql
|
||||||
|
.import "qrc:/js/helper.js" as Helperjs
|
||||||
|
.import "qrc:/js/news.js" as Newsjs
|
||||||
|
|
||||||
|
// IMAGE FUNCTIONS
|
||||||
|
|
||||||
|
function requestList(login,database,rootwindow,callback) {
|
||||||
|
//get list of own images and call download function
|
||||||
|
Helperjs.friendicaRequest(login,"/api/friendica/photos/list", rootwindow,function (helperobject){
|
||||||
|
print("return"+helperobject);
|
||||||
|
var obj=JSON.parse(helperobject);
|
||||||
|
Helperjs.readField("id",database,"imageData",login.username,function(AllStoredImages){
|
||||||
|
if (AllStoredImages.length>0){
|
||||||
|
for(var i=0;i< AllStoredImages.length;i++){
|
||||||
|
var position=Helperjs.inArray(obj,"resourceID",AllStoredImages[i]);
|
||||||
|
if (position>-1){obj.splice(position,1)}
|
||||||
|
//obj.splice(obj.indexOf(AllStoredImages[i]),1);// list of objects instead of list!!!
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
);
|
||||||
|
callback(obj);
|
||||||
|
})}
|
||||||
|
|
||||||
|
function dataRequest(login,photoID,database,rootwindow) {
|
||||||
|
// check if image exist and call download function
|
||||||
|
Helperjs.friendicaRequest(login,"/api/friendica/photo?photo_id="+photoID, rootwindow, function (obj){
|
||||||
|
try{ if(obj==""){currentImageNo=currentImageNo+1}else{
|
||||||
|
var image = JSON.parse(obj);
|
||||||
|
print('storeData() for ' + JSON.stringify(obj));
|
||||||
|
try{sprite.destroy();}catch(e){}
|
||||||
|
if (obj["link"]["0"]){var source=obj["link"]["0"]} else {var source=obj["link"]["4"]}//source for profile picture or original size
|
||||||
|
print("Source"+obj["link"]["0"]+source)
|
||||||
|
obj["source"]=source;
|
||||||
|
var filename=obj.filename;
|
||||||
|
if (filename==""){// check if file as any filename
|
||||||
|
if (obj.type=="image/jpeg") {obj["filename"]=obj["id"]+".jpg"}
|
||||||
|
else if (obj.type=="image/png") {obj["filename"]=obj["id"]+".png"}
|
||||||
|
}
|
||||||
|
// check if text name has valid image format ending, otherwise append appropriate ending
|
||||||
|
if(["jpg","png"].indexOf(obj["filename"].substring(obj["filename"].lastIndexOf(".")+1,obj["filename"].length))==-1){
|
||||||
|
print("falscheEndung: "+obj["filename"].substring(obj["filename"].lastIndexOf(".")+1,obj["filename"].length));
|
||||||
|
{ if (obj.type=="image/jpeg") {obj["filename"]=obj["filename"]+".jpg"}
|
||||||
|
else if (obj.type=="image/png") {obj["filename"]=obj["filename"]+".png"}
|
||||||
|
}
|
||||||
|
print("obj.Filename: "+obj["filename"]+" filename: "+filename)
|
||||||
|
}
|
||||||
|
saveImage(obj,login.imagestore,function(obj,sprite){
|
||||||
|
//sprite.destroy(500);
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
print('... check if a object exists: '+obj["id"])
|
||||||
|
var result = tx.executeSql('SELECT * from imageData where id = "'+obj["id"]+'"');
|
||||||
|
if(result.rows.length === 1) {// use update
|
||||||
|
print(obj["id"] +' exists, update it')
|
||||||
|
result = tx.executeSql('UPDATE imageData SET username ="' +login.username+ '",id="'+obj.id+'", created="'+obj.created+'", edited="'+obj.edited+'", profile="'+obj.profile+'", link="'+obj.source+'", filename="'+obj.filename+'",title="'+obj.title+'", desc="'+obj.desc+'", type="'+obj.type+'", width="'+obj.width+'", height="'+obj.height+'", album="'+obj.album+'", location="file://'+login.imagestore+'" where id="'+obj["id"]+'"');
|
||||||
|
} else {// use insert print('... does not exists, create it')
|
||||||
|
result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,obj.id,obj.created,obj.edited, obj.title, obj.desc, obj.album, obj.filename, obj.type, obj.height, obj.width,obj. profile,obj.source,'file://'+login.imagestore]);
|
||||||
|
print("Inserted");}
|
||||||
|
})})}}
|
||||||
|
catch (e){print("Data retrieval failure! "+ e+obj);}
|
||||||
|
})}
|
||||||
|
|
||||||
|
function saveImage(obj,storagedirectory,callback) {
|
||||||
|
// create image component from base64 code and save it
|
||||||
|
print("Storing "+storagedirectory+obj.filename+obj.width+"x"+obj.height);
|
||||||
|
var maxSize=Math.max(fotostab.width,fotostab.height);
|
||||||
|
var helpwidth=(obj.width<maxSize)?obj.width:maxSize;
|
||||||
|
var helpheight=(obj.height<maxSize)?obj.height:maxSize;
|
||||||
|
|
||||||
|
if (obj.width>obj.height){ //landscape
|
||||||
|
helpheight=helpwidth*obj.height/obj.width
|
||||||
|
} else { //portrait
|
||||||
|
helpwidth=helpheight*obj.width/obj.height
|
||||||
|
}
|
||||||
|
var component=Qt.createComponent("qrc:/qml/PhotoPlaceholder.qml");
|
||||||
|
var sprite = component.createObject(fotostab, {"x":0,"y":0,"imageName":storagedirectory+obj.filename ,"width":helpwidth,"height":helpheight,"source": obj.source,"downloadtype":"picture"});
|
||||||
|
callback(obj,sprite)
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteImageData(database,user,field,selection,callback) { // does nothing useful at the moment
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
print(' delete Image Data() for ' + field +"="+selection)
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
result = tx.executeSql('UPDATE imageData SET data="" where '+ field +'="'+selection+'"');
|
||||||
|
callback(result)})
|
||||||
|
}
|
||||||
|
|
||||||
|
function requestFriendsAlbumPictures(friend,rootwindow,callback){
|
||||||
|
// screenscraping of albums page of contact without user and password
|
||||||
|
Helperjs.friendicaWebRequest(friend.url.replace("profile","photos"),rootwindow,function(photohtml){
|
||||||
|
var photoarray=[];
|
||||||
|
var arr = photohtml.split("sidebar-photos-albums-li");
|
||||||
|
for (var i=2;i<arr.length;i++){
|
||||||
|
var albumlink = arr[i].substring(arr[i].indexOf('http'),arr[i].indexOf('class')-2);
|
||||||
|
var albumname=arr[i].substring(arr[i].indexOf('/span')+6,arr[i].indexOf('</a>')-1);
|
||||||
|
var album={'link':albumlink,'name':albumname}
|
||||||
|
photoarray.push(album);
|
||||||
|
}
|
||||||
|
//print("Album"+JSON.stringify(photoarray));
|
||||||
|
callback(photoarray)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function requestFriendsPictures(link,rootwindow,callback){
|
||||||
|
// screenscraping of pictures page for given album
|
||||||
|
Helperjs.friendicaWebRequest(link,rootwindow,function(photohtml){
|
||||||
|
var photoarray=[];
|
||||||
|
var basehtml=photohtml.substring(photohtml.indexOf('<base')+12,photohtml.indexOf('/>',photohtml.indexOf('<base'))-2);
|
||||||
|
|
||||||
|
// old theme
|
||||||
|
if (photohtml.indexOf("photo-album-image-wrapper-end")>-1){ //theme 1
|
||||||
|
var arr = photohtml.split("photo-album-image-wrapper-end");}
|
||||||
|
|
||||||
|
// other themes
|
||||||
|
if (photohtml.indexOf("photo-album-wrapper")>-1){ //theme 2
|
||||||
|
var photoarea=photohtml.substring(photohtml.indexOf("photo-album-wrapper"),photohtml.indexOf("photo-album-end"))
|
||||||
|
var arr = photoarea.split("</a>");}
|
||||||
|
|
||||||
|
for (var i=0;i<arr.length-1;i++){
|
||||||
|
var photoname=arr[i].substring(arr[i].lastIndexOf('alt')+5,arr[i].lastIndexOf('title')-2);
|
||||||
|
var thumblink=arr[i].substring(arr[i].lastIndexOf('<img')+10,arr[i].lastIndexOf('alt')-2);
|
||||||
|
|
||||||
|
var imagetype=thumblink.substring(thumblink.lastIndexOf("."));
|
||||||
|
var photolink=thumblink.substring(0,thumblink.length-imagetype.length-2)+"-0"+imagetype
|
||||||
|
if(thumblink.substring(0,4)!=="http"){thumblink=basehtml+thumblink}
|
||||||
|
if(photolink.substring(0,4)!=="http"){photolink=basehtml+photolink}
|
||||||
|
var photo={'link':photolink,'name':photoname,'thumb':thumblink}
|
||||||
|
photoarray.push(photo);
|
||||||
|
}
|
||||||
|
callback(photoarray)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CONFIG FUNCTIONS
|
||||||
|
|
||||||
|
function initDatabase(database) { // initialize the database object
|
||||||
|
var db =Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
print('initDatabase()'+database[0]+database[1]+database[2]+database[3])
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
print('... create table')
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS imageData(username TEXT,id INT, created TEXT,edited TEXT, title TEXT, desc TEXT, album TEXT,filename TEXT, type TEXT, height INT, width INT, profile INT, link TEXT,location TEXT)');
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS config(server TEXT, username TEXT, password TEXT, imagestore TEXT, maxnews INT, timerInterval INT, newsViewType TEXT,isActive INT)');
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS news(username TEXT, messagetype INT, text TEXT, created_at INT, in_reply_to_status_id INT, source TEXT, status_id INT, in_reply_to_user_id INT, geo TEXT,favorited TEXT, uid INT, statusnet_html TEXT, statusnet_conversation_id TEXT,like TEXT, dislike TEXT, attendyes TEXT,attendno TEXT, attendmaybe TEXT)');
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS contacts(username TEXT, id INT, name TEXT, screen_name TEXT, location TEXT,description TEXT, profile_image BLOB, url TEXT, protected TEXT, followers_count INT, friends_count INT, created_at TEXT, favourites_count TEXT, utc_offset TEXT, time_zone TEXT, statuses_count INT, following TEXT, verified TEXT, statusnet_blocking TEXT, notifications TEXT, statusnet_profile_url TEXT, cid INT, network TEXT, isFriend INT)');
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS groups(username TEXT, groupname TEXT, gid INT, members TEXT)');
|
||||||
|
})}
|
||||||
|
|
||||||
|
function storeConfig(database,obj) { // stores config to DB
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
print('storeConfig() for ' + obj.username)
|
||||||
|
print('database: ' + database[0]);
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
print('... check if a object exists: '+obj.username)
|
||||||
|
var result = tx.executeSql('SELECT * from config WHERE username="'+obj.username+'"');
|
||||||
|
if(result.rows.length === 1) {// use update
|
||||||
|
print(obj.username +' exists, update it');
|
||||||
|
var result2 = tx.executeSql('UPDATE config SET server="'+obj.server+'",password="'+obj.password+'", imagestore="'+obj.imagestore+'", maxnews="+obj.maxnews+", isActive=0 WHERE username="'+obj.username +'"');
|
||||||
|
var result3 = tx.executeSql('UPDATE config SET isActive=1 WHERE username !="'+obj.username +'"');
|
||||||
|
var result4 = tx.executeSql('UPDATE config SET maxnews='+obj.maxnews);
|
||||||
|
} else {// use insert print('... does not exists, create it')
|
||||||
|
var result2 = tx.executeSql('INSERT INTO config VALUES (?,?,?,?,?,?,?,?)', [obj.server, obj.username, obj.password, obj.imagestore, obj.maxnews, 0,"list",0]);
|
||||||
|
var result3 = tx.executeSql('UPDATE config SET isActive=1 WHERE username !="'+obj.username +'"');
|
||||||
|
var result4 = tx.executeSql('UPDATE config SET maxnews='+obj.maxnews);
|
||||||
|
print("Inserted");}
|
||||||
|
});}
|
||||||
|
|
||||||
|
function getServerConfig(login,rootwindow,callback){
|
||||||
|
// check server with given credentials
|
||||||
|
try {Helperjs.friendicaRequest(login,"/api/statusnet/config",rootwindow, function (obj){
|
||||||
|
var serverconfig = JSON.parse(obj);
|
||||||
|
var serverconfigString="import QtQuick 2.0; import QtQuick.Dialogs 1.2; MessageDialog{ visible: true; title:'Server';standardButtons: StandardButton.Ok;text: 'SUCCESS! \nName: "+serverconfig.site.name+"\nLanguage: "+serverconfig.site.language+
|
||||||
|
"\nEmail: "+serverconfig.site.email+"\nTimezone: "+serverconfig.site.timezone+"\nClosed: "+serverconfig.site.closed+
|
||||||
|
"\nText limit: "+serverconfig.site.textlimit+"\nShort Url length: "+serverconfig.site.shorturllength+
|
||||||
|
"\nFriendica version: "+serverconfig.site.friendica.FRIENDICA_VERSION+"\nDFRN version: "+serverconfig.site.friendica.DFRN_PROTOCOL_VERSION +
|
||||||
|
"\nDB Update version: "+serverconfig.site.friendica.DB_UPDATE_VERSION+"'}";
|
||||||
|
callback(serverconfigString);
|
||||||
|
})}
|
||||||
|
catch (e){callback (e);
|
||||||
|
}}
|
||||||
|
|
||||||
|
function readConfig(database,callback,filter,filtervalue) { // reads config
|
||||||
|
print('readConfig()')
|
||||||
|
if (filter){var where = " WHERE "+ filter +" = '" + filtervalue+"'";} else { var where="";}
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3],initDatabase(database));
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
var tables = tx.executeSql("SELECT * FROM sqlite_master WHERE type='table'");
|
||||||
|
if (tables.rows.length==0){print("no database");callback("")} else {
|
||||||
|
print('... read from database '+where)
|
||||||
|
var rs = tx.executeSql('select * from config'+where);
|
||||||
|
var rsArray=[];
|
||||||
|
if (rs.rows.length>0){
|
||||||
|
for(var i = 0; i < rs.rows.length; i++) {
|
||||||
|
rsArray.push(rs.rows.item(i))
|
||||||
|
}
|
||||||
|
var rsObject={server:rsArray[0].server,username:rsArray[0].username, password:rsArray[0].password,imagestore:rsArray[0].imagestore,maxnews:rsArray[0].maxnews,isActive:rsArray[0].isActive};
|
||||||
|
} else {
|
||||||
|
var rsObject=""
|
||||||
|
}
|
||||||
|
callback(rsObject);}}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function readActiveConfig(database){
|
||||||
|
var obj;
|
||||||
|
readConfig(database,function(config){
|
||||||
|
obj=config},"isActive", 0);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteConfig(database,userobj,callback) { // delete user data from DB
|
||||||
|
print('deleteConfig()')
|
||||||
|
if (userobj){var where = " WHERE username='"+ userobj.username+"' and server='"+userobj.server+"'";} else { return "no user selected!";}
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
if(!db) { return; }
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
print('... read from database '+where)
|
||||||
|
var rs = tx.executeSql('delete * from config'+where);
|
||||||
|
print(rs.toString);
|
||||||
|
callback(rs);
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
|
||||||
|
Item {
|
||||||
|
ComboBox{
|
||||||
|
id: selectionTypeCombo
|
||||||
|
width: 150
|
||||||
|
model: ["album", "type","filename"]
|
||||||
|
onCurrentIndexChanged:{
|
||||||
|
var login=Service.readActiveConfig(db);
|
||||||
|
if (currentText!==""){
|
||||||
|
photogroupModel.clear();
|
||||||
|
Service.readData(db, "imageData",function(filter){
|
||||||
|
for (var j=0;j<filter.length;j++){
|
||||||
|
Service.readField("data",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({imageString: obj[k].location+obj[k].filename,photoDescription:obj[k].filename})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (obj[0]) {photogroupModel.append({photoDescription: filter[j]})};
|
||||||
|
},currentText,filter[j]);
|
||||||
|
}},"username",login.username)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtMultimedia 5.0
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Rectangle {
|
||||||
|
VideoOutput {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: localCamera
|
||||||
|
}
|
||||||
|
Camera {
|
||||||
|
id: localCamera
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
id: shotButton
|
||||||
|
width: 200; height: 75
|
||||||
|
text: "Take Photo"
|
||||||
|
onClicked: {
|
||||||
|
localCamera.imageCapture.capture();
|
||||||
|
} }
|
||||||
|
Connections {
|
||||||
|
target: localCamera.imageCapture
|
||||||
|
onImageSaved: {
|
||||||
|
photofile= imagePaths.append({"path": path})
|
||||||
|
listView.positionViewAtEnd(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: photoFromCamera
|
||||||
|
anchors.fill: parent
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: photo
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Upload"
|
||||||
|
onClicked:{
|
||||||
|
var login=Service.readActiveConfig(db);
|
||||||
|
img.src=file;
|
||||||
|
Service.Upload(login,file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,250 @@
|
||||||
|
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/3;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=="") {
|
||||||
|
filesystem.Directory=userconfig.imagestore;
|
||||||
|
filesystem.makeDir("contacts");
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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",root.login.username,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)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
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-4
|
||||||
|
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);
|
||||||
|
friendComponent.state="large"}
|
||||||
|
}
|
||||||
|
Rectangle{
|
||||||
|
id: detailsrectangle
|
||||||
|
anchors.top: namelabel.bottom
|
||||||
|
anchors.topMargin: 2*mm
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
Flickable{
|
||||||
|
id:namelabelflickable
|
||||||
|
width: root.width-10*mm
|
||||||
|
height:wrapper.height-27*mm-3
|
||||||
|
boundsBehavior:Flickable.StopAtBounds
|
||||||
|
flickableDirection:Flickable.VerticalFlick
|
||||||
|
contentWidth:width
|
||||||
|
contentHeight: namelabeltext.height
|
||||||
|
clip:true
|
||||||
|
Text{
|
||||||
|
id:namelabeltext
|
||||||
|
//anchors.top: parent.top
|
||||||
|
width: namelabelflickable.width
|
||||||
|
height: 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: namelabelflickable.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:friendsTabView.width-4*mm; text:Qt.atob(friend.name)+" (@"+friend.screen_name+")"}
|
||||||
|
PropertyChanges { target: friendComponent; z: 2 }
|
||||||
|
PropertyChanges { target: wrapper; width:friendsTabView.width-3*mm;height:friendsTabView.height-14*mm}
|
||||||
|
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 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,174 @@
|
||||||
|
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 {
|
||||||
|
y:1
|
||||||
|
color: "white"
|
||||||
|
TabView{
|
||||||
|
id:friendsTabView
|
||||||
|
// property var contacts: []
|
||||||
|
// property var groups: []
|
||||||
|
|
||||||
|
tabPosition: Qt.TopEdge
|
||||||
|
x:mm
|
||||||
|
y:mm
|
||||||
|
width: root.width-5*mm
|
||||||
|
height: root.height-10*mm
|
||||||
|
currentIndex: 0
|
||||||
|
signal friendsSignal(var username)
|
||||||
|
signal contactsSignal(var username)
|
||||||
|
signal groupsSignal(var username)
|
||||||
|
onCurrentIndexChanged:{
|
||||||
|
if (currentIndex==0){friendsSignal(root.login.username)}
|
||||||
|
else if (currentIndex==1){contactsSignal(root.login.username)}
|
||||||
|
else if (currentIndex==2){groupsSignal(root.login.username)}
|
||||||
|
}
|
||||||
|
|
||||||
|
Tab{
|
||||||
|
title: qsTr("Friends")
|
||||||
|
Rectangle{
|
||||||
|
id: friendsGridTab
|
||||||
|
function showFriends(username){
|
||||||
|
try {friendsModel.clear()} catch(e){print(e)};
|
||||||
|
Helperjs.readData(db,"contacts",username,function(friends){
|
||||||
|
for (var i=0;i<friends.length;i++){
|
||||||
|
friendsModel.append({"friend":friends[i]});
|
||||||
|
}},"isFriend",1)
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
GridView {
|
||||||
|
id: friendsView
|
||||||
|
x:mm
|
||||||
|
y:updateFriendsButton.height+mm
|
||||||
|
width:friendsGridTab.width-2*mm
|
||||||
|
height:friendsGridTab.height-updateFriendsButton.height-2*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: {
|
||||||
|
friendsTabView.friendsSignal.connect(showFriends);
|
||||||
|
showFriends(root.login.username)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Tab{
|
||||||
|
title: qsTr("Other Contacts")
|
||||||
|
|
||||||
|
Rectangle{
|
||||||
|
id: contactsGridTab
|
||||||
|
function showContacts(username){
|
||||||
|
try {contactsModel.clear()} catch(e){print(e)};
|
||||||
|
Helperjs.readData(db, "contacts",root.login.username,function(friendsobject){
|
||||||
|
for (var j=0;j<friendsobject.length;j++){
|
||||||
|
contactsModel.append({"friend":friendsobject[j]});
|
||||||
|
}
|
||||||
|
},"isFriend",0)}
|
||||||
|
|
||||||
|
GridView {
|
||||||
|
id: contactsView
|
||||||
|
x:mm
|
||||||
|
y:mm
|
||||||
|
width:contactsGridTab.width-2*mm
|
||||||
|
height:contactsGridTab.height-2*mm
|
||||||
|
clip: true
|
||||||
|
cellHeight: 16*mm
|
||||||
|
cellWidth: 17*mm
|
||||||
|
add: Transition {
|
||||||
|
NumberAnimation { properties: "x,y"; from: 300; duration: 1000 }
|
||||||
|
}
|
||||||
|
model: contactsModel
|
||||||
|
delegate: FriendComponent { }
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel{id: contactsModel}
|
||||||
|
Component.onCompleted: {
|
||||||
|
friendsTabView.contactsSignal.connect(showContacts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tab{
|
||||||
|
title: qsTr("Groups")
|
||||||
|
Rectangle{
|
||||||
|
id: groupsGridTab
|
||||||
|
function showGroups(username){
|
||||||
|
try {groupsModel.clear()} catch(e){print(e)};
|
||||||
|
print("showGroups"+username);
|
||||||
|
Helperjs.readData(db, "groups",root.login.username,function(groupsobject){
|
||||||
|
for (var j=0;j<groupsobject.length;j++){
|
||||||
|
groupsModel.append({"group":groupsobject[j]});
|
||||||
|
}})}
|
||||||
|
Button {
|
||||||
|
id: updateGroupsButton
|
||||||
|
text: qsTr("Update")
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
onClicked: {
|
||||||
|
print("Update groups");
|
||||||
|
Newsjs.requestGroups(root.login,root.db,root,function(){
|
||||||
|
showGroups(root.login.username)})}
|
||||||
|
}
|
||||||
|
GridView {
|
||||||
|
id: groupsView
|
||||||
|
x:mm
|
||||||
|
y:updateGroupsButton.height+mm
|
||||||
|
width:groupsGridTab.width-2*mm
|
||||||
|
height:groupsGridTab.height-updateGroupsButton.height-2*mm
|
||||||
|
clip: true
|
||||||
|
cellHeight: 16*mm
|
||||||
|
cellWidth: 17*mm
|
||||||
|
add: Transition {
|
||||||
|
NumberAnimation { properties: "x,y"; from: 300; duration: 1000 }
|
||||||
|
}
|
||||||
|
model: groupsModel
|
||||||
|
delegate: GroupComponent { }
|
||||||
|
}
|
||||||
|
ListModel{
|
||||||
|
id: groupsModel
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
friendsTabView.groupsSignal.connect(showGroups);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
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: groupComponent
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wrapper
|
||||||
|
width: 16*mm
|
||||||
|
height: 15*mm
|
||||||
|
border.color: "grey"
|
||||||
|
color:"white"
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: namelabel
|
||||||
|
x: 1
|
||||||
|
width: wrapper.width-2
|
||||||
|
height: 3*mm
|
||||||
|
text: group.groupname
|
||||||
|
|
||||||
|
color: "#303030"
|
||||||
|
font.pixelSize: 3*mm
|
||||||
|
anchors.centerIn:parent
|
||||||
|
}
|
||||||
|
Button{
|
||||||
|
id:infobutton
|
||||||
|
width: 5*mm
|
||||||
|
height: 5*mm
|
||||||
|
text:"?"
|
||||||
|
anchors.top: namelabel.bottom;anchors.topMargin: 3
|
||||||
|
onClicked:{
|
||||||
|
print("State: "+ groupComponent.state+groupView.contentY);
|
||||||
|
groupComponent.state="large"}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle{
|
||||||
|
id: detailsrectangle
|
||||||
|
anchors.top: infobutton.bottom
|
||||||
|
anchors.topMargin: 2*mm
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
Component { id:footerComponent
|
||||||
|
Rectangle{
|
||||||
|
border.color: "#EEEEEE"
|
||||||
|
border.width: 1
|
||||||
|
width:parent.width
|
||||||
|
height:6*mm
|
||||||
|
Text{
|
||||||
|
font.pixelSize: 3*mm
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text:qsTr("+")
|
||||||
|
}
|
||||||
|
MouseArea{anchors.fill:parent
|
||||||
|
onClicked:{var contactitems="";
|
||||||
|
readData(db,"contacts",root.login.username, function(contacts){for (var i=0;i<contacts.length;i++){
|
||||||
|
contactitems=contactitems+"MenuItem{text:'"+contacts[i].screen_name+"'; onTriggered: groupModel.append(' @"+contacts[i]+"')}"
|
||||||
|
}},"isFriend",0)
|
||||||
|
var menuString="import QtQuick.Controls 1.4; Menu {"+contactitems+"}";
|
||||||
|
print("menustring: "+menuString);
|
||||||
|
var contactlistObject=Qt.createQmlObject(menuString,messageSend,"contactmenuOutput");
|
||||||
|
contactlistObject.popup();
|
||||||
|
Newsjs.addToGroup
|
||||||
|
}}}}
|
||||||
|
|
||||||
|
Component { id:groupMember
|
||||||
|
Rectangle{
|
||||||
|
border.color: "#EEEEEE"
|
||||||
|
border.width: 1
|
||||||
|
width:parent.width
|
||||||
|
height:6*mm
|
||||||
|
Text{
|
||||||
|
font.pixelSize: 3*mm
|
||||||
|
anchors.left: parent.left
|
||||||
|
text:groupmember.screen_name
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
ListView{
|
||||||
|
id:namelabeltext
|
||||||
|
anchors.top: parent.top
|
||||||
|
width: root.width-10*mm
|
||||||
|
height:wrapper.height-20*mm
|
||||||
|
clip: true
|
||||||
|
spacing: 0
|
||||||
|
footer: footerComponent
|
||||||
|
model: groupModel
|
||||||
|
delegate: groupMember
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel{id: groupModel}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
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 {
|
||||||
|
y:1
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,286 @@
|
||||||
|
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+friendicaActivities.height+4*mm),profileImage.height+user_name.height+mm)
|
||||||
|
|
||||||
|
// property var friendica_activities
|
||||||
|
property string conversation_id: ""
|
||||||
|
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*mm
|
||||||
|
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{id: friendicaActivities
|
||||||
|
spacing:mm
|
||||||
|
Label{color: "grey"
|
||||||
|
font.pixelSize: 1.5*mm
|
||||||
|
text: friendica_activities.likeText
|
||||||
|
}
|
||||||
|
Label{color: "grey"
|
||||||
|
font.pixelSize: 1.5*mm
|
||||||
|
text: friendica_activities.dislikeText
|
||||||
|
}
|
||||||
|
Label{color: "grey"
|
||||||
|
font.pixelSize: 1.5*mm
|
||||||
|
text: friendica_activities.attendyesText
|
||||||
|
}
|
||||||
|
Label{color: "grey"
|
||||||
|
font.pixelSize: 1.5*mm
|
||||||
|
text: friendica_activities.attendnoText
|
||||||
|
}
|
||||||
|
Label{color: "grey"
|
||||||
|
font.pixelSize: 1.5*mm
|
||||||
|
text: friendica_activities.attendmaybeText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Row {
|
||||||
|
CheckBox{id:likeCheckbox
|
||||||
|
height:3*mm
|
||||||
|
width:8*mm
|
||||||
|
checked:(newsitemobject.liked==1)?true:false
|
||||||
|
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
|
||||||
|
checked: (newsitemobject.disliked==1)?true:false
|
||||||
|
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);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
|
@ -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) }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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("Source: "+source+"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
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
}}}
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
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
|
||||||
|
y:1
|
||||||
|
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].id,root.db,fotorectangle);
|
||||||
|
newImagesProgress.visible=true //download first image
|
||||||
|
}}
|
||||||
|
onCurrentImageNoChanged:{
|
||||||
|
if(currentImageNo<newImages.length){Service.dataRequest(root.login,newImages[currentImageNo].id,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);}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Rectangle{
|
||||||
|
property string photofile:"../images/Update.png"
|
||||||
|
color: "grey"
|
||||||
|
|
||||||
|
FileDialog {
|
||||||
|
id: fileDialog
|
||||||
|
title: "Please choose a file"
|
||||||
|
folder: shortcuts.pictures
|
||||||
|
selectMultiple: true
|
||||||
|
onAccepted: {
|
||||||
|
photofile=fileDialog.fileUrls[0];
|
||||||
|
console.log("You chose: " + fileDialog.fileUrls)
|
||||||
|
// img.src=file;
|
||||||
|
}
|
||||||
|
onRejected: {
|
||||||
|
console.log("Canceled")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Component.onCompleted: {fileDialog.open()}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: photoFromFilesystem
|
||||||
|
x: 20;y:50
|
||||||
|
height: 200
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: photofile
|
||||||
|
|
||||||
|
onStatusChanged:{
|
||||||
|
if (photoFromFilesystem.status == Image.Ready) {
|
||||||
|
Layoutjs.showFriends(db)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: "Upload"
|
||||||
|
onClicked:{
|
||||||
|
var login=Service.readActiveConfig(db);
|
||||||
|
Service.uploadMedia(login,photofile, function(returnvalue){print("Upload return"+returnvalue)})
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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",root.login.username,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
|
|
@ -0,0 +1,112 @@
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
print("Current contact"+JSON.stringify(newContacts[currentContact]));
|
||||||
|
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
|
||||||
|
try{var imagename=login.imagestore+"contacts/"+contact.screen_name+".jpg";
|
||||||
|
var component=Qt.createComponent("qrc:/qml/PhotoPlaceholder.qml");
|
||||||
|
print("imageName "+imagename+" source "+ contact.profile_image_url)
|
||||||
|
var sprite = component.createObject(root, {"fillMode": "Image.PreserveAspectFit","x":root.width,"y":50,"imageName":imagename,"source": contact.profile_image_url,"downloadtype":"contact"});} catch(e){print("Fehler beim Profilbild"+e)}
|
||||||
|
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("Contacts")
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>js/layout.js</file>
|
||||||
|
<file>js/photoworker.js</file>
|
||||||
|
<file>js/service.js</file>
|
||||||
|
<file>qml/FriendComponent.qml</file>
|
||||||
|
<file>qml/MessageSend.qml</file>
|
||||||
|
<file>qml/Newsitem.qml</file>
|
||||||
|
<file>qml/PhotoComponent.qml</file>
|
||||||
|
<file>qml/PhotogroupComponent.qml</file>
|
||||||
|
<file>qml/PhotoPlaceholder.qml</file>
|
||||||
|
<file>qml/friendiqa.qml</file>
|
||||||
|
<file>qml/PhotoTab.qml</file>
|
||||||
|
<file>qml/ConfigTab.qml</file>
|
||||||
|
<file>qml/FriendsTab.qml</file>
|
||||||
|
<file>qml/NewsTab.qml</file>
|
||||||
|
<file>js/news.js</file>
|
||||||
|
<file>js/newsworker.js</file>
|
||||||
|
<file>js/helper.js</file>
|
||||||
|
<file>images/defaultcontact.jpg</file>
|
||||||
|
<file>qml/InfoBox.qml</file>
|
||||||
|
<file>qml/GroupComponent.qml</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
|
@ -0,0 +1,49 @@
|
||||||
|
#include "filesystem.h"
|
||||||
|
|
||||||
|
FILESYSTEM *FILESYSTEM::instance()
|
||||||
|
{
|
||||||
|
static FILESYSTEM filesystem;
|
||||||
|
return &filesystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILESYSTEM::FILESYSTEM(QObject *parent) : QObject(parent){}
|
||||||
|
|
||||||
|
void FILESYSTEM::setDirectory(QString Directory)
|
||||||
|
{
|
||||||
|
if (Directory!=m_Directory) {
|
||||||
|
m_Directory = Directory;
|
||||||
|
emit directoryChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FILESYSTEM::Directory() const
|
||||||
|
{
|
||||||
|
return m_Directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FILESYSTEM::makeDir(QString name)
|
||||||
|
{
|
||||||
|
QDir dir(m_Directory);
|
||||||
|
if (dir.mkdir(name)){
|
||||||
|
emit success(name);
|
||||||
|
}
|
||||||
|
else {emit error(name,1);}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FILESYSTEM::rmDir(QString name)
|
||||||
|
{
|
||||||
|
QDir dir(m_Directory);
|
||||||
|
if (dir.rmdir(name)){
|
||||||
|
emit success(name);
|
||||||
|
}
|
||||||
|
else {emit error(name,1);}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FILESYSTEM::rmFile(QString name)
|
||||||
|
{
|
||||||
|
QDir dir(m_Directory);
|
||||||
|
if(dir.remove(name)){
|
||||||
|
emit success(name);
|
||||||
|
}
|
||||||
|
else {emit error(name,1);}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
#ifndef FILESYSTEM_H
|
||||||
|
#define FILESYSTEM_H
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class FILESYSTEM : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString Directory READ Directory WRITE setDirectory NOTIFY directoryChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
static FILESYSTEM *instance();
|
||||||
|
explicit FILESYSTEM(QObject *parent = 0);
|
||||||
|
void setDirectory(QString Directory);
|
||||||
|
QString Directory() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void directoryChanged();
|
||||||
|
void success(QString data);
|
||||||
|
void error(QString data, int code);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
//void setDirectory(QString Directory);
|
||||||
|
void makeDir(QString name);
|
||||||
|
void rmDir(QString name);
|
||||||
|
void rmFile(QString name);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
//void onReplyError(QNetworkReply::NetworkError code);
|
||||||
|
// void onReplySuccess();
|
||||||
|
//void onReadyRead();
|
||||||
|
// void onSSLError(const QList<QSslError> &errors);
|
||||||
|
|
||||||
|
private:
|
||||||
|
//QByteArray buffer;
|
||||||
|
QString m_Directory;
|
||||||
|
//QString m_login;
|
||||||
|
//QHash<QString, QString> params;
|
||||||
|
//QHash<QString, QString> files;
|
||||||
|
|
||||||
|
//QNetworkAccessManager manager;
|
||||||
|
//QNetworkRequest request;
|
||||||
|
//QNetworkReply *reply;
|
||||||
|
|
||||||
|
//QString bufferToString();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FILSYSTEM_H
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QtQml/QQmlEngine>
|
||||||
|
#include <QtQuick>
|
||||||
|
#include "xhr.h"
|
||||||
|
#include "filesystem.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
QQuickView view;
|
||||||
|
|
||||||
|
|
||||||
|
XHR* xhr = XHR::instance();
|
||||||
|
view.rootContext()->setContextProperty("xhr", xhr);
|
||||||
|
FILESYSTEM* filesystem = FILESYSTEM::instance();
|
||||||
|
view.rootContext()->setContextProperty("filesystem", filesystem);
|
||||||
|
view.setSource(QUrl("qrc:/qml/friendiqa.qml"));
|
||||||
|
view.show();
|
||||||
|
view.connect(view.rootContext()->engine(), SIGNAL(quit()), &app, SLOT(quit()));
|
||||||
|
return app.exec();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
#include "uploadableimage.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <QBuffer>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
void UploadableImage::setSource(const QString &a) {
|
||||||
|
if (a != m_source) {
|
||||||
|
m_source = a;
|
||||||
|
//m_base64 = "";
|
||||||
|
m_mimetype = "";
|
||||||
|
m_filename = "";
|
||||||
|
|
||||||
|
qDebug() << "UploadableImage::setSource : " << m_source;
|
||||||
|
|
||||||
|
if (m_source=="") {
|
||||||
|
emit sourceChanged();
|
||||||
|
//emit base64Changed();
|
||||||
|
emit mimetypeChanged();
|
||||||
|
emit filenameChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage fullimage = QImage(QUrl(m_source).toLocalFile());
|
||||||
|
if (fullimage.width() > 800 || fullimage.height() > 800) {
|
||||||
|
if (fullimage.width() > fullimage.height()) {
|
||||||
|
m_image = fullimage.scaledToWidth(800);
|
||||||
|
} else {
|
||||||
|
m_image = fullimage.scaledToHeight(800);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
m_image = fullimage;
|
||||||
|
}
|
||||||
|
qDebug() << "UploadableImage::setSource : " << m_image.width() << "x" << m_image.height();
|
||||||
|
emit sourceChanged();
|
||||||
|
|
||||||
|
QFileInfo fi(m_source);
|
||||||
|
|
||||||
|
m_filename = fi.fileName();
|
||||||
|
emit filenameChanged();
|
||||||
|
|
||||||
|
QString filetype = fi.suffix().toUpper();
|
||||||
|
if (filetype!="PNG" && filetype!="JPG") {
|
||||||
|
filetype = "JPG";
|
||||||
|
}
|
||||||
|
qDebug() << "UploadableImage::setSource : " << "Saving as " << filetype;
|
||||||
|
|
||||||
|
m_mimetype = "image/"+filetype.toLower();
|
||||||
|
emit mimetypeChanged();
|
||||||
|
|
||||||
|
/*
|
||||||
|
QByteArray byteArray;
|
||||||
|
QBuffer buffer(&byteArray);
|
||||||
|
m_image.save(&buffer, filetype.toLatin1().constData());
|
||||||
|
QString b64 = QString::fromLatin1(byteArray.toBase64().data());
|
||||||
|
|
||||||
|
for(int k=0; k<b64.length(); k+=76) {
|
||||||
|
m_base64 += b64.mid(k,76) + "\n";
|
||||||
|
}
|
||||||
|
m_base64 = m_base64.trimmed();
|
||||||
|
|
||||||
|
emit base64Changed();
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UploadableImage::source() const {
|
||||||
|
return m_source;
|
||||||
|
}
|
||||||
|
|
||||||
|
//QString UploadableImage::base64() const {
|
||||||
|
// return m_base64;
|
||||||
|
//}
|
||||||
|
|
||||||
|
QString UploadableImage::filename() const {
|
||||||
|
return m_filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UploadableImage::mimetype() const {
|
||||||
|
return m_mimetype;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray UploadableImage::bytes() {
|
||||||
|
QByteArray byteArray;
|
||||||
|
QBuffer buffer(&byteArray);
|
||||||
|
m_image.save(&buffer, "PNG");
|
||||||
|
return byteArray;
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef UPLOADABLEIMAGE_H
|
||||||
|
#define UPLOADABLEIMAGE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QQuickItem>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
class UploadableImage : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged)
|
||||||
|
//Q_PROPERTY(QString base64 READ base64 NOTIFY base64Changed)
|
||||||
|
Q_PROPERTY(QString filename READ filename NOTIFY filenameChanged)
|
||||||
|
Q_PROPERTY(QString mimetype READ mimetype NOTIFY mimetypeChanged)
|
||||||
|
Q_PROPERTY(QByteArray bytes READ bytes)
|
||||||
|
|
||||||
|
public:
|
||||||
|
void setSource(const QString &a);
|
||||||
|
QString source() const;
|
||||||
|
|
||||||
|
//QString base64() const;
|
||||||
|
QString filename() const;
|
||||||
|
QString mimetype() const;
|
||||||
|
|
||||||
|
QByteArray bytes();
|
||||||
|
signals:
|
||||||
|
void sourceChanged();
|
||||||
|
//void base64Changed();
|
||||||
|
void filenameChanged();
|
||||||
|
void mimetypeChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_source;
|
||||||
|
QImage m_image;
|
||||||
|
//QString m_base64;
|
||||||
|
QString m_filename;
|
||||||
|
QString m_mimetype;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // UPLOADABLEIMAGE_H
|
|
@ -0,0 +1,168 @@
|
||||||
|
#include "xhr.h"
|
||||||
|
|
||||||
|
#include <QHttpPart>
|
||||||
|
#include <QTextCodec>
|
||||||
|
#include <QUrlQuery>
|
||||||
|
|
||||||
|
#include "uploadableimage.h"
|
||||||
|
|
||||||
|
XHR *XHR::instance()
|
||||||
|
{
|
||||||
|
static XHR xhr;
|
||||||
|
return &xhr;
|
||||||
|
}
|
||||||
|
|
||||||
|
XHR::XHR(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
request.setSslConfiguration(QSslConfiguration::defaultConfiguration());
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::setUrl(QString url)
|
||||||
|
{
|
||||||
|
if (url!=m_url) {
|
||||||
|
m_url = url;
|
||||||
|
emit urlChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::setLogin(QString login)
|
||||||
|
{
|
||||||
|
if (login!=m_login) {
|
||||||
|
m_login = login;
|
||||||
|
emit loginChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QString XHR::url() const
|
||||||
|
{
|
||||||
|
return m_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XHR::login() const
|
||||||
|
{
|
||||||
|
return m_login;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::setParam(QString name, QString value)
|
||||||
|
{
|
||||||
|
params.insert(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::setImageFileParam(QString name, QString url)
|
||||||
|
{
|
||||||
|
files.insert(name, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::clearParams()
|
||||||
|
{
|
||||||
|
files.clear();
|
||||||
|
params.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::get()
|
||||||
|
{
|
||||||
|
QUrlQuery query;
|
||||||
|
|
||||||
|
QHashIterator<QString, QString> i(params);
|
||||||
|
while(i.hasNext()) {
|
||||||
|
i.next();
|
||||||
|
query.addQueryItem(i.key(), i.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl requrl(m_url);
|
||||||
|
requrl.setQuery(query);
|
||||||
|
|
||||||
|
QByteArray loginData = m_login.toLocal8Bit().toBase64();
|
||||||
|
QString headerData = "Basic " + loginData;
|
||||||
|
request.setRawHeader("Authorization", headerData.toLocal8Bit());
|
||||||
|
|
||||||
|
|
||||||
|
request.setUrl(requrl);
|
||||||
|
reply = manager.get(request);
|
||||||
|
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &XHR::onReplySuccess);
|
||||||
|
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onReplyError(QNetworkReply::NetworkError)));
|
||||||
|
connect(reply, &QNetworkReply::readyRead, this, &XHR::onReadyRead);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::post()
|
||||||
|
{
|
||||||
|
qDebug() << "start post to " << m_url;
|
||||||
|
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
|
||||||
|
|
||||||
|
QHashIterator<QString, QString> iparams(params);
|
||||||
|
while(iparams.hasNext()) {
|
||||||
|
iparams.next();
|
||||||
|
qDebug() << "\t add param " << iparams.key() << " : " << iparams.value();
|
||||||
|
QHttpPart textPart;
|
||||||
|
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"" + iparams.key() + "\""));
|
||||||
|
|
||||||
|
|
||||||
|
textPart.setBody(iparams.value().toUtf8());
|
||||||
|
multiPart->append(textPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
UploadableImage uimg;
|
||||||
|
QHashIterator<QString, QString> ifiles(files);
|
||||||
|
while(ifiles.hasNext()) {
|
||||||
|
ifiles.next();
|
||||||
|
|
||||||
|
uimg.setSource(ifiles.value());
|
||||||
|
qDebug() << "\t image: " << uimg.mimetype() << ", " << ifiles.key();
|
||||||
|
|
||||||
|
QHttpPart imagePart;
|
||||||
|
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant(uimg.mimetype()));
|
||||||
|
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"" + ifiles.key() + "\"; filename=\""+uimg.filename()+"\""));
|
||||||
|
imagePart.setBody(uimg.bytes());
|
||||||
|
multiPart->append(imagePart);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray loginData = m_login.toLocal8Bit().toBase64();
|
||||||
|
QString headerData = "Basic " + loginData;
|
||||||
|
request.setRawHeader(QByteArray("Authorization"), headerData.toLocal8Bit());
|
||||||
|
|
||||||
|
request.setUrl(m_url);
|
||||||
|
reply = manager.post(request, multiPart);
|
||||||
|
qDebug() << "\t request sent";
|
||||||
|
connect(reply, &QNetworkReply::finished, this, &XHR::onReplySuccess);
|
||||||
|
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(onReplyError(QNetworkReply::NetworkError)));
|
||||||
|
connect(reply, &QNetworkReply::readyRead, this, &XHR::onReadyRead);
|
||||||
|
connect(reply, &QNetworkReply::sslErrors, this, &XHR::onSSLError);
|
||||||
|
qDebug() << "\t reply signals connected";
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::onReplyError(QNetworkReply::NetworkError code)
|
||||||
|
{
|
||||||
|
qDebug() << code;
|
||||||
|
emit this->error( bufferToString(), (int) code);
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::onReplySuccess()
|
||||||
|
{
|
||||||
|
qDebug() << "!";
|
||||||
|
emit this->success( bufferToString() );
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::onReadyRead()
|
||||||
|
{
|
||||||
|
qDebug() << ".";
|
||||||
|
buffer += reply->readAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XHR::onSSLError(const QList<QSslError> &errors)
|
||||||
|
{
|
||||||
|
qDebug() << "XHR::onSSLError :" ;
|
||||||
|
QListIterator<QSslError> ierrs(errors);
|
||||||
|
while(ierrs.hasNext()) {
|
||||||
|
qDebug() << "\t" << ierrs.next().errorString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString XHR::bufferToString()
|
||||||
|
{
|
||||||
|
return QTextCodec::codecForName("utf-8")->toUnicode(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
#ifndef XHR_H
|
||||||
|
#define XHR_H
|
||||||
|
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class XHR : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged)
|
||||||
|
Q_PROPERTY(QString login READ login WRITE setLogin NOTIFY loginChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
static XHR *instance();
|
||||||
|
|
||||||
|
explicit XHR(QObject *parent = 0);
|
||||||
|
|
||||||
|
void setUrl(QString url);
|
||||||
|
// void setLogin(QString login);
|
||||||
|
|
||||||
|
QString url() const;
|
||||||
|
QString login() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void urlChanged();
|
||||||
|
void loginChanged();
|
||||||
|
void success(QString data);
|
||||||
|
void error(QString data, int code);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setLogin(QString login);
|
||||||
|
void setParam(QString name, QString value);
|
||||||
|
void setImageFileParam(QString name, QString url);
|
||||||
|
void clearParams();
|
||||||
|
void post();
|
||||||
|
void get();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onReplyError(QNetworkReply::NetworkError code);
|
||||||
|
void onReplySuccess();
|
||||||
|
void onReadyRead();
|
||||||
|
void onSSLError(const QList<QSslError> &errors);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QByteArray buffer;
|
||||||
|
QString m_url;
|
||||||
|
QString m_login;
|
||||||
|
QHash<QString, QString> params;
|
||||||
|
QHash<QString, QString> files;
|
||||||
|
|
||||||
|
QNetworkAccessManager manager;
|
||||||
|
QNetworkRequest request;
|
||||||
|
QNetworkReply *reply;
|
||||||
|
|
||||||
|
QString bufferToString();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // XHR_H
|
|
@ -0,0 +1,40 @@
|
||||||
|
# NOTICE:
|
||||||
|
#
|
||||||
|
# Application name defined in TARGET has a corresponding QML filename.
|
||||||
|
# If name defined in TARGET is changed, the following needs to be done
|
||||||
|
# to match new name:
|
||||||
|
# - corresponding QML filename must be changed
|
||||||
|
# - desktop icon filename must be changed
|
||||||
|
# - desktop filename must be changed
|
||||||
|
# - icon definition filename in desktop file must be changed
|
||||||
|
# - translation filenames have to be changed
|
||||||
|
|
||||||
|
# The name of your application
|
||||||
|
TARGET = friendiqa
|
||||||
|
CONFIG += debug
|
||||||
|
QT += qml quick gui widgets
|
||||||
|
|
||||||
|
SOURCES += common/friendiqa.cpp \
|
||||||
|
common/uploadableimage.cpp \
|
||||||
|
common/xhr.cpp \
|
||||||
|
common/filesystem.cpp
|
||||||
|
|
||||||
|
RESOURCES = application.qrc
|
||||||
|
|
||||||
|
OTHER_FILES += qml/friendiqa.qml \
|
||||||
|
translations/*.ts \
|
||||||
|
qml/*.qml
|
||||||
|
js/*.js
|
||||||
|
|
||||||
|
# German translation is enabled as an example. If you aren't
|
||||||
|
# planning to localize your app, remember to comment out the
|
||||||
|
# following TRANSLATIONS line. And also do not forget to
|
||||||
|
# modify the localized app name in the the .desktop file.
|
||||||
|
TRANSLATIONS += translations/friendiqa-de.ts
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
common/uploadableimage.h \
|
||||||
|
common/xhr.h \
|
||||||
|
common/filesystem.h
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,12 @@
|
||||||
|
WorkerScript.onMessage = function(msg) {
|
||||||
|
msg.model.clear();
|
||||||
|
for (var j=0;j<msg.albums.length;j++){
|
||||||
|
if (msg.albums[j]) {
|
||||||
|
var albumobject=msg.albums[j];
|
||||||
|
var data=({"albumobject": albumobject,"foreignPicture": msg.foreignPicture})}
|
||||||
|
// print("Albums:"+j+msg.albums.length+JSON.stringify(data));
|
||||||
|
msg.model.append(data);}
|
||||||
|
if (j==msg.albums.length){
|
||||||
|
msg.model.sync()
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
.pragma library
|
||||||
|
.import QtQuick.LocalStorage 2.0 as Sql
|
||||||
|
|
||||||
|
function friendicaRequest(login,api,rootwindow,callback) {
|
||||||
|
var xhrequest= new XMLHttpRequest();
|
||||||
|
xhrequest.onreadystatechange = function() {
|
||||||
|
if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
|
||||||
|
} else if(xhrequest.readyState === XMLHttpRequest.DONE) {
|
||||||
|
try{ if (xhrequest.responseText!=""){
|
||||||
|
callback(xhrequest.responseText)
|
||||||
|
}else{
|
||||||
|
showMessage("Error",api+" NO RESPONSE",rootwindow)
|
||||||
|
callback(xhrequest.responseText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e){
|
||||||
|
showMessage("Error", api+" "+e,rootwindow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhrequest.open("GET", login.server+api,true,login.username,Qt.atob(login.password));
|
||||||
|
xhrequest.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function friendicaPostRequest(login,api,rootwindow,callback) {
|
||||||
|
var xhrequest= new XMLHttpRequest();
|
||||||
|
xhrequest.onreadystatechange = function() {
|
||||||
|
if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
|
||||||
|
} else if(xhrequest.readyState === XMLHttpRequest.DONE) {
|
||||||
|
try{ if (xhrequest.responseText!=""){
|
||||||
|
callback(xhrequest.responseText)
|
||||||
|
}else{
|
||||||
|
showMessage("Error",api+" NO RESPONSE",rootwindow)
|
||||||
|
callback(xhrequest.responseText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e){
|
||||||
|
showMessage("Error", api+" "+e,rootwindow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhrequest.open("POST", login.server+api,true,login.username,Qt.atob(login.password));
|
||||||
|
xhrequest.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function friendicaWebRequest(url,rootwindow,callback) {
|
||||||
|
var xhrequest = new XMLHttpRequest();
|
||||||
|
xhrequest.onreadystatechange = function() {
|
||||||
|
if (xhrequest.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
|
||||||
|
} else if(xhrequest.readyState === XMLHttpRequest.DONE) {
|
||||||
|
try{ callback(xhrequest.responseText);
|
||||||
|
}
|
||||||
|
catch (e){
|
||||||
|
showMessage("Error",url+" "+e, rootwindow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xhrequest.open("GET", url,true);
|
||||||
|
xhrequest.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function readData(database,table,username,callback,filter,filtervalue) { // reads and applies data from DB
|
||||||
|
if (filter){
|
||||||
|
var where = " AND "+ filter +" = '" + filtervalue+"'";
|
||||||
|
} else { var where="";}
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
if(!db) { return; }
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
// print('select * from '+table'+where username= "'+username+'"'+'where);
|
||||||
|
var rsArray=[];
|
||||||
|
var rs = tx.executeSql('select * from '+table+' where username= "'+username+'"'+where);
|
||||||
|
for(var i = 0; i < rs.rows.length; i++) {
|
||||||
|
rsArray.push(rs.rows.item(i))
|
||||||
|
}
|
||||||
|
callback(rsArray);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function readField(field,database,table, username, callback,filter,filtervalue) { // reads and applies data from DB
|
||||||
|
if (filter){
|
||||||
|
var where = " AND "+ filter +" = '" + filtervalue+"'";
|
||||||
|
} else { var where="";}
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
if(!db) { return; }
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
// print('... read from database ' + field)
|
||||||
|
var rsArray=[];
|
||||||
|
print('select DISTINCT '+field+' from '+table+' WHERE username="'+username+'"'+where+' ORDER BY '+field+' ASC');
|
||||||
|
var rs = tx.executeSql('select DISTINCT '+field+' from '+table+' WHERE username="'+username+'"'+where+' ORDER BY '+field+' ASC');
|
||||||
|
for(var i = 0; i < rs.rows.length; i++) {
|
||||||
|
rsArray.push(rs.rows.item(i)[field])
|
||||||
|
}
|
||||||
|
callback(rsArray);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showMessage(header,message,rootwindow){
|
||||||
|
var messageString='import QtQuick 2.0; import QtQuick.Dialogs 1.2; MessageDialog{ visible: true; title:"'+header+'";standardButtons: StandardButton.Ok; text:" '+message+'"}';
|
||||||
|
var messageObject=Qt.createQmlObject(messageString,rootwindow,"messageOutput");
|
||||||
|
}
|
||||||
|
|
||||||
|
function inArray(list, prop, val) {
|
||||||
|
if (list.length > 0 ) {
|
||||||
|
for (var i in list) { if (list[i][prop] === val) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} return -1;
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
function showFriends(db) {
|
||||||
|
Service.readActiveConfig(db,function(login){
|
||||||
|
Service.requestFriends(login.url,login.user,login.password,displayFriends);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function displayFriends(obj){
|
||||||
|
for (var i=0; i<obj.length; i++){
|
||||||
|
print(obj[i]);
|
||||||
|
if (obj[i]) {friendsModel.append({"friendName": obj[i]});
|
||||||
|
};
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
function ensureVisibility(c,f)
|
||||||
|
{
|
||||||
|
if (f.contentX >= c.x)
|
||||||
|
f.contentX = c.x;
|
||||||
|
else if (f.contentX+f.width <= c.x+c.width)
|
||||||
|
f.contentX = c.x+c.width-f.width;
|
||||||
|
if (f.contentY >= c.y)
|
||||||
|
f.contentY = c.y;
|
||||||
|
else if (f.contentY+f.height <= c.y+c.height)
|
||||||
|
f.contentY = c.y+c.height-f.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createObject(objectQml,qmlParameters,parentitem,callback) {
|
||||||
|
var component = Qt.createComponent(objectQml);
|
||||||
|
if (component.status === Component.Ready || component.status === Component.Error)
|
||||||
|
finishCreation(component,qmlParameters,parentitem,callback);
|
||||||
|
else
|
||||||
|
component.statusChanged.connect(finishCreation(qmlParameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishCreation(component,qmlParameters,parentitem,callback) {
|
||||||
|
if (component.status === Component.Ready) {
|
||||||
|
var createdObject = component.createObject(parentitem, qmlParameters);
|
||||||
|
if (createdObject === null)
|
||||||
|
print("Error creating image"); }
|
||||||
|
else if (component.status === Component.Error)
|
||||||
|
print("Error loading component:"+component.errorString());
|
||||||
|
else {print("created")}
|
||||||
|
callback(createdObject);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,311 @@
|
||||||
|
.pragma library
|
||||||
|
.import QtQuick.LocalStorage 2.0 as Sql
|
||||||
|
.import "qrc:/js/helper.js" as Helperjs
|
||||||
|
|
||||||
|
function requestFriends(login,database,rootwindow,callback){
|
||||||
|
// return array of friends
|
||||||
|
Helperjs.friendicaRequest(login,"/api/statuses/friends", rootwindow,function (obj){
|
||||||
|
var friends=JSON.parse(obj);
|
||||||
|
for (var i=0;i<friends.length;i++){ friends[i].isFriend=1}
|
||||||
|
callback(friends)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function requestGroups(login,database,rootwindow,callback){
|
||||||
|
// retrieve, save and return groups, currently not implemented
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
Helperjs.friendicaRequest(login,"/api/friendica/group_show",rootwindow, function (obj){
|
||||||
|
var groups=JSON.parse(obj);
|
||||||
|
for (var i=0;i<groups.length;i++){
|
||||||
|
var memberarray=[]; for (var user in groups[i].user){memberarray.push(parseInt(groups[i].user[user].id))}
|
||||||
|
//print("Members: "+groups[i].user)
|
||||||
|
//updateGroupInDB(login,database,groups[i])
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
var result = tx.executeSql('SELECT * from groups where username="'+login.username+'" AND gid = "'+groups[i].gid+'"'); // check for group id
|
||||||
|
if(result.rows.length === 1) {// use update
|
||||||
|
print(groups[i].gid +' exists, update it')
|
||||||
|
result = tx.executeSql('UPDATE groups SET username="'+login.username+'", groupname="'+groups[i].name+'", members="'+JSON.stringify(memberarray)+'"');
|
||||||
|
} else {// use insert
|
||||||
|
result = tx.executeSql('INSERT INTO groups VALUES (?,?,?,?)', [login.username,groups[i].name,groups[i].gid,JSON.stringify(memberarray)])}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//Helperjs.readData(database,"groups",login.username,callback)
|
||||||
|
callback()
|
||||||
|
});}
|
||||||
|
|
||||||
|
function getFriendsTimeline(login,database,contacts,rootwindow,callback){// retrieve and return timeline since last news, return contacts which are not friends for update (friends can be updated in Friendstab)
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
var parameter = "";
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
var result = tx.executeSql('SELECT status_id from news WHERE username="'+login.username+'" ORDER BY status_id DESC LIMIT 1'); // check for last news id
|
||||||
|
try{parameter="&since_id="+result.rows.item(0).status_id;}catch(e){};})
|
||||||
|
var newContacts=[];
|
||||||
|
Helperjs.friendicaRequest(login,"/api/statuses/friends_timeline"+parameter, rootwindow,function (obj){
|
||||||
|
var news=JSON.parse(obj);
|
||||||
|
for (var i=0;i<news.length;i++){
|
||||||
|
if(contacts.indexOf(news[i].user.id)==-1 && !(inArray(newContacts,"id",news[i].user.id))){
|
||||||
|
news[i].user.isFriend=0;
|
||||||
|
newContacts.push(news[i].user);
|
||||||
|
}
|
||||||
|
if (news[i].friendica_activities.like.length>0){
|
||||||
|
print("Like Contact"+JSON.stringify(news[i].friendica_activities.like));
|
||||||
|
for (var j=0;j<news[i].friendica_activities.like.length;j++){
|
||||||
|
if(contacts.indexOf(news[i].friendica_activities.like[j].id)==-1 && !(inArray(newContacts,"id",news[i].friendica_activities.like[j].id))){
|
||||||
|
news[i].friendica_activities.like[j].isFriend=0;
|
||||||
|
newContacts.push(news[i].friendica_activities.like[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (news[i].friendica_activities.dislike.length>0){
|
||||||
|
print("DisLike Contact"+JSON.stringify(news[i].friendica_activities.dislike));
|
||||||
|
for (var k=0;j<news[k].friendica_activities.dislike.length;k++){
|
||||||
|
if(contacts.indexOf(news[i].friendica_activities.dislike[k].id)==-1 && !(inArray(newContacts,"id",news[i].friendica_activties.dislike[k].id))){
|
||||||
|
news[i].friendica_activities.dislike[k].isFriend=0;
|
||||||
|
newContacts.push(news[i].friendica_activities.dislike[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback(news,newContacts)
|
||||||
|
})}
|
||||||
|
|
||||||
|
function storeNews(login,database,news,rootwindow,callback){
|
||||||
|
// save news after contacts download, call next function
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
for (var i=0;i<news.length;i++){
|
||||||
|
print('store news data for ' + news[i].id+JSON.stringify(news[i].friendica_activities));
|
||||||
|
var ausdruck=news[i];
|
||||||
|
var likearray=[]; for (var user in news[i].friendica_activities.like){likearray.push(parseInt(news[i].friendica_activities.like[user].id))}
|
||||||
|
var dislikearray=[]; for (var user in news[i].friendica_activities.dislike){parseInt(news[i].friendica_activities.dislike[user].id)}
|
||||||
|
var attendyesarray=[]; for (var user in news[i].friendica_activities.attendyes){attendyesarray.push(parseInt(news[i].friendica_activities.attendyes[user].id))}
|
||||||
|
var attendnoarray=[]; for (var user in news[i].friendica_activities.attendno){attendnoarray.push(parseInt(news[i].friendica_activities.attendno[user].id))}
|
||||||
|
var attendmaybearray=[]; for (var user in news[i].friendica_activities.attendmaybe){attendmaybearray.push(parseInt(news[i].friendica_activities.attendmaybe[user].id))}
|
||||||
|
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
var result = tx.executeSql('SELECT * from news where status_id = "'+news[i].id+'"'); // check for news id
|
||||||
|
if(result.rows.length === 1) {// use update
|
||||||
|
print(news[i].id +' exists, update it')
|
||||||
|
result = tx.executeSql('UPDATE news SET username="'+login.username+'", messagetype=0, text="'+Qt.btoa(news[i].text)+'", created_at="'+Date.parse(cleanDate(news[i].created_at))+'", in_reply_to_status_id="'+news[i].in_reply_to_status_id+'", source="'+news[i].source+'", status_id="'+news[i].id+'", in_reply_to_user_id="'+news[i].in_reply_to_user_id+'", geo="'+news[i].geo+'", favorited="'+news[i].favorited+'", uid="'+news[i].user.id+'", statusnet_html="'+Qt.btoa(news[i].status_html)+'", statusnet_conversation_id="'+news[i].statusnet_conversation_id+'",like="'+JSON.stringify(likearray)+'", dislike="'+JSON.stringify(dislikearray)+'", attendyes="'+JSON.stringify(attendyesarray)+'",attendno="'+JSON.stringify(attendnoarray)+'",attendmaybe="'+JSON.stringify(attendmaybearray)+'" where status_id="'+news[i].status_id+'"');
|
||||||
|
} else {// use insert
|
||||||
|
result = tx.executeSql('INSERT INTO news (username,messagetype,text,created_at,in_reply_to_status_id,source,status_id,in_reply_to_user_id,geo,favorited,uid,statusnet_html,statusnet_conversation_id,like,dislike,attendyes,attendno,attendmaybe) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,0,Qt.btoa(news[i].text),Date.parse(cleanDate(news[i].created_at)), news[i].in_reply_to_status_id, news[i].source, news[i].id,news[i].in_reply_to_user_id,news[i].geo,news[i].favorited, news[i].user.id,Qt.btoa(news[i].statusnet_html),news[i].statusnet_conversation_id, JSON.stringify(likearray),JSON.stringify(dislikearray),JSON.stringify(attendyesarray),JSON.stringify(attendnoarray),JSON.stringify(attendmaybearray)])}})
|
||||||
|
}
|
||||||
|
getDirectMessage(login,database,rootwindow,callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDirectMessage(login,database,rootwindow,callback){
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
Helperjs.friendicaRequest(login,"/api/direct_messages/all",rootwindow, function (obj){
|
||||||
|
var messages=JSON.parse(obj);
|
||||||
|
for (var i=0;i<messages.length;i++){
|
||||||
|
// print('store message data for '+JSON.stringify(messages[i]));
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
var result = tx.executeSql('SELECT * from news where status_id = "'+messages[i].id+'"'); // check for news id
|
||||||
|
if(result.rows.length === 1) {// use update
|
||||||
|
print(messages[i].id +' exists, update it')
|
||||||
|
result = tx.executeSql('UPDATE news SET username="'+login.username+'", messagetype=1, text="'+Qt.btoa(messages[i].text)+'", created_at="'+Date.parse(cleanDate(messages[i].created_at))+'", source="Friendica", status_id="'+messages[i].id+'", uid="'+messages[i].sender.id+'", statusnet_html="'+Qt.btoa(messages[i].text)+'" where status_id="'+messages[i].status_id+'"');
|
||||||
|
} else {// use insert
|
||||||
|
result = tx.executeSql('INSERT INTO news (username,messagetype,text,created_at,source,status_id,uid,statusnet_html) VALUES (?,?,?,?,?,?,?,?)', [login.username,1,Qt.btoa(messages[i].text),Date.parse(cleanDate(messages[i].created_at)), "Friendica", messages[i].id, messages[i].sender.id,Qt.btoa(messages[i].text)])}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
getNotifications(login,database,rootwindow,callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNotifications(login,database,rootwindow,callback){
|
||||||
|
Helperjs.friendicaRequest(login,"/api/friendica/notifications", rootwindow,function (obj){
|
||||||
|
var messages=JSON.parse(obj);
|
||||||
|
for (var i=0;i<messages.length;i++){
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
//print('store message data for '+JSON.stringify(messages[i]));
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
var result = tx.executeSql('SELECT * from news where status_id = "'+messages[i].id+'"'); // check for news id
|
||||||
|
if(result.rows.length === 1) {// use update
|
||||||
|
print(messages[i].id +' exists, update it')
|
||||||
|
result = tx.executeSql('UPDATE news SET username="'+login.username+'", messagetype=2, text="'+Qt.btoa(messages[i].msg_html)+'", created_at="'+messages[i].timestamp+'", source="Friendica", status_id="'+messages[i].id+'", uid="'+messages[i].uid+'", statusnet_html="'+Qt.btoa(messages[i].msg_html)+'", statusnet_conversation_id="'+messages[i].parent+'" where status_id="'+messages[i].id+'"');
|
||||||
|
} else {// use insert
|
||||||
|
result = tx.executeSql('INSERT INTO news (username,messagetype,text,created_at,source,status_id, uid,statusnet_html,statusnet_conversation_id) VALUES (?,?,?,?,?,?,?,?,?)', [login.username,2,Qt.btoa(messages[i].msg_html),messages[i].timestamp,"Friendica", messages[i].id, messages[i].uid,Qt.btoa(messages[i].msg_html),messages[i].parent])}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
newsfromdb(database,login.username,callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
function newsfromdb(database,username,callback,contact,stop_time){
|
||||||
|
// return news before stop_time (used by More button), in brackets of 20 entries, or by specified contact
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
if (!stop_time){var stop="";
|
||||||
|
try{var rs = tx.executeSql('select created_at from news WHERE username="'+username+'" ORDER BY created_at DESC LIMIT 1');
|
||||||
|
stop="<="+rs.rows.item(0).created_at}catch(e){stop="<99999999999999"}}
|
||||||
|
else{var stop="<"+stop_time}
|
||||||
|
var contactfilter="";if(contact){contactfilter=" AND uid='"+contact+"'"}
|
||||||
|
var newsrs=tx.executeSql('select * from news WHERE username="'+username+'" AND created_at'+stop+contactfilter+' ORDER BY created_at DESC LIMIT 20');
|
||||||
|
var newsArray=[];
|
||||||
|
for(var i = 0; i < newsrs.rows.length; i++) {
|
||||||
|
newsArray.push(newsrs.rows.item(i));
|
||||||
|
Helperjs.readData(database,"contacts",username,function(userdata){
|
||||||
|
newsArray[i].user=userdata[0];
|
||||||
|
},"id",newsArray[i].uid);
|
||||||
|
if(newsArray[i].in_reply_to_user_id){
|
||||||
|
Helperjs.readData(database,"contacts",username,function(replytodata){
|
||||||
|
newsArray[i].reply_user=replytodata[0];
|
||||||
|
},"id",newsArray[i].in_reply_to_user_id);
|
||||||
|
}
|
||||||
|
if (newsArray[i].messagetype==0){
|
||||||
|
//userdata for likes
|
||||||
|
var likeArray=JSON.parse(newsArray[i].like);
|
||||||
|
var likeHelper=[];
|
||||||
|
for (var j=0;j<likeArray.length;j++){
|
||||||
|
Helperjs.readData(database,"contacts",username,function(userdata){
|
||||||
|
likeHelper[j]=userdata[0];
|
||||||
|
},"id",likeArray[j]);
|
||||||
|
}
|
||||||
|
newsArray[i].like=likeHelper;
|
||||||
|
//userdata for dislikes
|
||||||
|
var dislikeArray=JSON.parse(newsArray[i].dislike);
|
||||||
|
var dislikeHelper=[];
|
||||||
|
for (var k=0;k<dislikeArray.length;k++){
|
||||||
|
Helperjs.readData(database,"contacts",username,function(userdata){
|
||||||
|
dislikeHelper[j]=userdata[0];
|
||||||
|
},"id",dislikeArray[k]);
|
||||||
|
}
|
||||||
|
newsArray[i].dislike=dislikeHelper;
|
||||||
|
//userdata for attendyes
|
||||||
|
var attendyesArray=JSON.parse(newsArray[i].attendyes);
|
||||||
|
var attendyesHelper=[];
|
||||||
|
for (var l=0;l<attendyesArray.length;l++){
|
||||||
|
Helperjs.readData(database,"contacts",username,function(userdata){
|
||||||
|
attendyesHelper[j]=userdata[0];
|
||||||
|
},"id",attendyesArray[l]);
|
||||||
|
}
|
||||||
|
newsArray[i].attendyes=attendyesHelper;
|
||||||
|
//userdata for attendno
|
||||||
|
var attendnoArray=JSON.parse(newsArray[i].attendno);
|
||||||
|
var attendnoHelper=[];
|
||||||
|
for (var m=0;m<attendnoArray.length;m++){
|
||||||
|
Helperjs.readData(database,"contacts",username,function(userdata){
|
||||||
|
attendnoHelper[j]=userdata[0];
|
||||||
|
},"id",attendnoArray[m]);
|
||||||
|
}
|
||||||
|
newsArray[i].attendno=attendnoHelper;
|
||||||
|
|
||||||
|
//userdata for attendmaybe
|
||||||
|
var attendmaybeArray=JSON.parse(newsArray[i].attendmaybe);
|
||||||
|
var attendmaybeHelper=[];
|
||||||
|
for (var n=0;n<attendmaybeArray.length;n++){
|
||||||
|
Helperjs.readData(database,"contacts",username,function(userdata){
|
||||||
|
attendmaybeHelper[j]=userdata[0];
|
||||||
|
},"id",attendmaybeArray[l]);
|
||||||
|
}
|
||||||
|
newsArray[i].attendmaybe=attendmaybeHelper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback(newsArray)});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteNews(login,database,newsid,rootwindow,callback){
|
||||||
|
Helperjs.friendicaPostRequest(login,"/api/statuses/destroy?id="+newsid, rootwindow,function (obj){
|
||||||
|
print("Delete "+obj);
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
print('delete news data for ' + newsid);
|
||||||
|
db.transaction( function(tx) {var result = tx.executeSql('DELETE from news where status_id ='+newsid); // delete news id
|
||||||
|
Helperjs.showMessage("Delete",result,rootwindow)});
|
||||||
|
})}
|
||||||
|
|
||||||
|
function retweetNews(login,database,newsid,rootwindow,callback){
|
||||||
|
Helperjs.friendicaRequest(login,"/api/statuses/retweet?id="+newsid, rootwindow,function (obj){
|
||||||
|
var answer=JSON.parse(obj);
|
||||||
|
Helperjs.showMessage("Repost",answer,rootwindow);
|
||||||
|
})}
|
||||||
|
|
||||||
|
function favorite(login,favorite,newsid,rootwindow){
|
||||||
|
// toggle favorites
|
||||||
|
if(favorite){ Helperjs.friendicaPostRequest(login,"/api/favorites/create?id="+newsid, rootwindow,function (obj){
|
||||||
|
print("Favorite "+obj);
|
||||||
|
})}
|
||||||
|
else {Helperjs.friendicaPostRequest(login,"/api/favorites/destroy?id="+newsid, rootwindow,function (obj){
|
||||||
|
print("Favorite destroyed "+obj);
|
||||||
|
})}
|
||||||
|
}
|
||||||
|
|
||||||
|
function likerequest(login,database,toggle,verb,newsid,rootwindow){
|
||||||
|
Helperjs.friendicaPostRequest(login,"/api/friendica/activity/"+verb+"?id="+newsid, rootwindow,function (obj){
|
||||||
|
print("likereturn "+obj);
|
||||||
|
if (obj=='"ok"'){
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
db.transaction( function(tx) {var result = tx.executeSql('UPDATE news SET '+verb+'d ='+toggle+' where status_id ='+newsid);
|
||||||
|
})}})
|
||||||
|
}
|
||||||
|
|
||||||
|
function like(login,database,toggle,verb,newsid,rootwindow){
|
||||||
|
if(verb=="like"&& toggle==1){
|
||||||
|
likerequest(login,database,1,"like",newsid,rootwindow);
|
||||||
|
likerequest(login,database,0,"undislike",newsid,rootwindow);}
|
||||||
|
if(verb=="dislike"&& toggle==1){
|
||||||
|
likerequest(login,database,1,"dislike",newsid,rootwindow);
|
||||||
|
likerequest(login,database,0,"unlike",newsid,rootwindow);}
|
||||||
|
if(toggle==0){
|
||||||
|
likerequest(login,database,0,"un"+verb,newsid,rootwindow);}
|
||||||
|
}
|
||||||
|
|
||||||
|
function attend(login,database,attend,newsid,rootwindow,callback){
|
||||||
|
Helperjs.friendicaPostRequest(login,"/api/friendica/activity/attend"+attend+"?id="+newsid, rootwindow,function (obj){
|
||||||
|
var attendReturn=JSON.parse(obj);
|
||||||
|
// print("attend: "+obj);
|
||||||
|
//if (attendReturn=="OK")
|
||||||
|
{
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
db.transaction( function(tx) {var result = tx.executeSql('UPDATE news SET attend="+attend+" where status_id ='+newsid);
|
||||||
|
callback();
|
||||||
|
})}})}
|
||||||
|
|
||||||
|
function requestConversation(login,database,newsid,rootwindow,callback){
|
||||||
|
Helperjs.friendicaRequest(login,"/api/conversation/show?id="+newsid,rootwindow, function (obj){
|
||||||
|
print(obj+JSON.stringify(obj));
|
||||||
|
var news=JSON.parse(obj);
|
||||||
|
for (var i=0;i<news.length;i++){
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
print('store news data for ' + news[i].id);
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
var result = tx.executeSql('SELECT * from news where status_id = "'+news[i].id+'"'); // check for news id
|
||||||
|
if(result.rows.length === 1) {// use update
|
||||||
|
print(news[i].id +' exists, update it')
|
||||||
|
result = tx.executeSql('UPDATE news SET username="'+login.username+'", messagetype=0, text="'+Qt.btoa(news[i].text)+'", truncated="'+news[i].truncated+'", created_at="'+Date.parse(cleanDate(news[i].created_at))+'", in_reply_to_status_id="'+news[i].in_reply_to_status_id+'", source="'+news[i].source+'", status_id="'+news[i].id+'", in_reply_to_user_id="'+news[i].in_reply_to_user_id+'", geo="'+news[i].geo+'", favorited="'+news[i].favorited+'", uid="'+news[i].user.id+'", statusnet_html="'+Qt.btoa(news[i].status_html)+'", statusnet_conversation_id="'+news[i].statusnet_conversation_id+'", attachments="'+news[i].attachments+'" where status_id="'+news[i].status_id+'"');
|
||||||
|
} else {// use insert
|
||||||
|
result = tx.executeSql('INSERT INTO news VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,0,Qt.btoa(news[i].text),news[i].truncated,Date.parse(cleanDate(news[i].created_at)), news[i].in_reply_to_status_id, news[i].source, news[i].id,news[i].in_reply_to_user_id,news[i].geo,news[i].favorited, news[i].user.id,Qt.btoa(news[i].statusnet_html),news[i].statusnet_conversation_id, news[i].attachments,0,0,0]);
|
||||||
|
}});
|
||||||
|
if(news[i].user.following!=true){
|
||||||
|
updateContactInDB(login,database,rootwindow,news[i].user)}
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
);}
|
||||||
|
|
||||||
|
function conversationfromdb(database,user,conversationId,callback){
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
print('select * from news WHERE statusnet_conversation_id='+conversationId+' ORDER BY status_id DESC');
|
||||||
|
var newsrs=tx.executeSql('select * from news WHERE statusnet_conversation_id='+conversationId+' ORDER BY status_id DESC');
|
||||||
|
var newsArray=[];
|
||||||
|
for(var i = 0; i < newsrs.rows.length; i++) {
|
||||||
|
newsArray.push(newsrs.rows.item(i))
|
||||||
|
Helperjs.readData(database,"contacts",function(userdata){
|
||||||
|
newsArray[i].user=userdata[0];
|
||||||
|
},"id",newsArray[i].uid);
|
||||||
|
}
|
||||||
|
callback(newsArray);
|
||||||
|
});}
|
||||||
|
|
||||||
|
function inArray(list, prop, val) {
|
||||||
|
if (list.length > 0 ) {
|
||||||
|
for (var i in list) { if (list[i][prop] === val) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanDate(date){
|
||||||
|
var cleanedDate= date.slice(0,3)+", "+date.slice(8,11)+date.slice(4,7)+date.slice(25,30)+date.slice(10,25);
|
||||||
|
return cleanedDate
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
WorkerScript.onMessage = function(msg) {
|
||||||
|
if(msg.appendnews!==true){ msg.model.clear()};
|
||||||
|
for (var j=0;j<msg.news.length;j++){
|
||||||
|
if (msg.news[j]) {
|
||||||
|
var newsitemobject=msg.news[j];
|
||||||
|
var likeText="";var dislikeText="";var attendyesText="";var attendnoText="";var attendmaybeText="";
|
||||||
|
if (newsitemobject.messagetype==0){
|
||||||
|
if (msg.news[j].like.length>0){
|
||||||
|
if (msg.news[j].like.length==1){likeText= Qt.atob(msg.news[j].like[0].name)+" "+ qsTr("likes this.")}
|
||||||
|
else {likeText= msg.news[j].like.length+" "+ qsTr("like this.")}
|
||||||
|
}
|
||||||
|
if (msg.news[j].dislike.length>0){
|
||||||
|
if (msg.news[j].dislike.length==1){dislikeText= QT.atob(msg.news[j].dislike[0].name)+" "+ qsTr("doesn't like this.")}
|
||||||
|
else {dislikeText= msg.news[j].dislike.length+" "+ qsTr("don't like this.")}
|
||||||
|
}
|
||||||
|
if (msg.news[j].attendyes.length>0){
|
||||||
|
if (msg.news[j].attendyes.length==1){attendyesText= Qt.atob(msg.news[j].attendyes[0].name)+" "+ qsTr("will attend.")}
|
||||||
|
else {attendyesText= msg.news[j].attendyes.length+" "+ qsTr("persons will attend.")}
|
||||||
|
}
|
||||||
|
if (msg.news[j].attendno.length>0){
|
||||||
|
if (msg.news[j].attendno.length==1){attendnoText= Qt.atob(msg.news[j].attendno[0].name)+" "+ qsTr("will not attend.")}
|
||||||
|
else {attendnoText= msg.news[j].attendno.length+" "+ qsTr("persons will not attend.")}
|
||||||
|
}
|
||||||
|
if (msg.news[j].attendmaybe.length>0){
|
||||||
|
if (msg.news[j].attendmaybe.length==1){attendmaybeText= Qt.atob(msg.news[j].attendmaybe[0].name)+" "+ qsTr("may attend.")}
|
||||||
|
else {attendmaybeText= msg.news[j].attendmaybe.length+" "+ qsTr("persons may attend.")}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var friendica_activities={likeText:likeText,dislikeText:dislikeText,attendyesText:attendyesText,attendnoText:attendnoText,attendmaybeText:attendmaybeText}
|
||||||
|
var seconds=(msg.currentTime-newsitemobject.created_at)/1000;
|
||||||
|
var timestring="";
|
||||||
|
if (seconds<60) {timestring=seconds+" "+qsTr("seconds") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<90){timestring=Math.round(seconds/60)+" "+qsTr("minute") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<3600){timestring=Math.round(seconds/60)+" "+qsTr("minutes") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<5400){timestring=Math.round(seconds/3600)+" "+qsTr("hour") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<86400){timestring=Math.round(seconds/3600)+" "+qsTr("hours") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<129600){timestring=Math.round(seconds/86400)+" "+qsTr("day") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<3888000){timestring=Math.round(seconds/86400)+" "+qsTr("days") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<5832000){timestring=Math.round(seconds/3888000)+" "+qsTr("month") +" "+qsTr("ago");}
|
||||||
|
else if (seconds<69984000){timestring=Math.round(seconds/3888000)+" "+qsTr("months") +" "+qsTr("ago");}
|
||||||
|
else {timestring=Math.round(seconds/69984000)+" "+qsTr("years") +" "+qsTr("ago");}
|
||||||
|
var data=({"newsitemobject": newsitemobject,"dateDiff":timestring,"friendica_activities":friendica_activities})}
|
||||||
|
// print("News:"+j+msg.news.length+JSON.stringify(data));
|
||||||
|
msg.model.append(data);}
|
||||||
|
if (j==msg.news.length){
|
||||||
|
msg.model.sync()
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
WorkerScript.onMessage = function(msg) {
|
||||||
|
if (msg.firstalbum==0){msg.model.clear();}
|
||||||
|
var limit=0; if (msg.albums.length-msg.firstalbum<20){limit=msg.albums.length} else{limit=msg.firstalbum+20}
|
||||||
|
for (var j=msg.firstalbum;j<limit;j++){
|
||||||
|
if (msg.albums[msg.firstalbum]) {
|
||||||
|
// print("album"+msg.albums[j].name);
|
||||||
|
if(msg.foreignPicture){
|
||||||
|
var albumname=msg.albums[j].name.trim();var albumlink=msg.albums[j].link
|
||||||
|
}else{
|
||||||
|
var albumname=msg.albums[j].toString();var albumlink=""}
|
||||||
|
msg.model.append({"albumlink":albumlink,"foreignPicture":msg.foreignPicture,"albumname":albumname});
|
||||||
|
msg.model.sync()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,222 @@
|
||||||
|
//.pragma library
|
||||||
|
.import QtQuick.LocalStorage 2.0 as Sql
|
||||||
|
.import "qrc:/js/helper.js" as Helperjs
|
||||||
|
.import "qrc:/js/news.js" as Newsjs
|
||||||
|
|
||||||
|
// IMAGE FUNCTIONS
|
||||||
|
|
||||||
|
function requestList(login,database,rootwindow,callback) {
|
||||||
|
//get list of own images and call download function
|
||||||
|
Helperjs.friendicaRequest(login,"/api/friendica/photos/list", rootwindow,function (helperobject){
|
||||||
|
print("return"+helperobject);
|
||||||
|
var obj=JSON.parse(helperobject);
|
||||||
|
Helperjs.readField("id",database,"imageData",login.username,function(AllStoredImages){
|
||||||
|
if (AllStoredImages.length>0){
|
||||||
|
for(var i=0;i< AllStoredImages.length;i++){
|
||||||
|
var position=Helperjs.inArray(obj,"resourceID",AllStoredImages[i]);
|
||||||
|
if (position>-1){obj.splice(position,1)}
|
||||||
|
//obj.splice(obj.indexOf(AllStoredImages[i]),1);// list of objects instead of list!!!
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
);
|
||||||
|
callback(obj);
|
||||||
|
})}
|
||||||
|
|
||||||
|
function dataRequest(login,photoID,database,rootwindow) {
|
||||||
|
// check if image exist and call download function
|
||||||
|
Helperjs.friendicaRequest(login,"/api/friendica/photo?photo_id="+photoID, rootwindow, function (obj){
|
||||||
|
try{ if(obj==""){currentImageNo=currentImageNo+1}else{
|
||||||
|
var image = JSON.parse(obj);
|
||||||
|
print('storeData() for ' + JSON.stringify(obj));
|
||||||
|
try{sprite.destroy();}catch(e){}
|
||||||
|
if (obj["link"]["0"]){var source=obj["link"]["0"]} else {var source=obj["link"]["4"]}//source for profile picture or original size
|
||||||
|
print("Source"+obj["link"]["0"]+source)
|
||||||
|
obj["source"]=source;
|
||||||
|
var filename=obj.filename;
|
||||||
|
if (filename==""){// check if file as any filename
|
||||||
|
if (obj.type=="image/jpeg") {obj["filename"]=obj["id"]+".jpg"}
|
||||||
|
else if (obj.type=="image/png") {obj["filename"]=obj["id"]+".png"}
|
||||||
|
}
|
||||||
|
// check if text name has valid image format ending, otherwise append appropriate ending
|
||||||
|
if(["jpg","png"].indexOf(obj["filename"].substring(obj["filename"].lastIndexOf(".")+1,obj["filename"].length))==-1){
|
||||||
|
print("falscheEndung: "+obj["filename"].substring(obj["filename"].lastIndexOf(".")+1,obj["filename"].length));
|
||||||
|
{ if (obj.type=="image/jpeg") {obj["filename"]=obj["filename"]+".jpg"}
|
||||||
|
else if (obj.type=="image/png") {obj["filename"]=obj["filename"]+".png"}
|
||||||
|
}
|
||||||
|
print("obj.Filename: "+obj["filename"]+" filename: "+filename)
|
||||||
|
}
|
||||||
|
saveImage(obj,login.imagestore,function(obj,sprite){
|
||||||
|
//sprite.destroy(500);
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
print('... check if a object exists: '+obj["id"])
|
||||||
|
var result = tx.executeSql('SELECT * from imageData where id = "'+obj["id"]+'"');
|
||||||
|
if(result.rows.length === 1) {// use update
|
||||||
|
print(obj["id"] +' exists, update it')
|
||||||
|
result = tx.executeSql('UPDATE imageData SET username ="' +login.username+ '",id="'+obj.id+'", created="'+obj.created+'", edited="'+obj.edited+'", profile="'+obj.profile+'", link="'+obj.source+'", filename="'+obj.filename+'",title="'+obj.title+'", desc="'+obj.desc+'", type="'+obj.type+'", width="'+obj.width+'", height="'+obj.height+'", album="'+obj.album+'", location="file://'+login.imagestore+'" where id="'+obj["id"]+'"');
|
||||||
|
} else {// use insert print('... does not exists, create it')
|
||||||
|
result = tx.executeSql('INSERT INTO imageData VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', [login.username,obj.id,obj.created,obj.edited, obj.title, obj.desc, obj.album, obj.filename, obj.type, obj.height, obj.width,obj. profile,obj.source,'file://'+login.imagestore]);
|
||||||
|
print("Inserted");}
|
||||||
|
})})}}
|
||||||
|
catch (e){print("Data retrieval failure! "+ e+obj);}
|
||||||
|
})}
|
||||||
|
|
||||||
|
function saveImage(obj,storagedirectory,callback) {
|
||||||
|
// create image component from base64 code and save it
|
||||||
|
print("Storing "+storagedirectory+obj.filename+obj.width+"x"+obj.height);
|
||||||
|
var maxSize=Math.max(fotostab.width,fotostab.height);
|
||||||
|
var helpwidth=(obj.width<maxSize)?obj.width:maxSize;
|
||||||
|
var helpheight=(obj.height<maxSize)?obj.height:maxSize;
|
||||||
|
|
||||||
|
if (obj.width>obj.height){ //landscape
|
||||||
|
helpheight=helpwidth*obj.height/obj.width
|
||||||
|
} else { //portrait
|
||||||
|
helpwidth=helpheight*obj.width/obj.height
|
||||||
|
}
|
||||||
|
var component=Qt.createComponent("qrc:/qml/PhotoPlaceholder.qml");
|
||||||
|
var sprite = component.createObject(fotostab, {"x":0,"y":0,"imageName":storagedirectory+obj.filename ,"width":helpwidth,"height":helpheight,"source": obj.source,"downloadtype":"picture"});
|
||||||
|
callback(obj,sprite)
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteImageData(database,user,field,selection,callback) { // does nothing useful at the moment
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
print(' delete Image Data() for ' + field +"="+selection)
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
result = tx.executeSql('UPDATE imageData SET data="" where '+ field +'="'+selection+'"');
|
||||||
|
callback(result)})
|
||||||
|
}
|
||||||
|
|
||||||
|
function requestFriendsAlbumPictures(friend,rootwindow,callback){
|
||||||
|
// screenscraping of albums page of contact without user and password
|
||||||
|
Helperjs.friendicaWebRequest(friend.url.replace("profile","photos"),rootwindow,function(photohtml){
|
||||||
|
var photoarray=[];
|
||||||
|
var arr = photohtml.split("sidebar-photos-albums-li");
|
||||||
|
for (var i=2;i<arr.length;i++){
|
||||||
|
var albumlink = arr[i].substring(arr[i].indexOf('http'),arr[i].indexOf('class')-2);
|
||||||
|
var albumname=arr[i].substring(arr[i].indexOf('/span')+6,arr[i].indexOf('</a>')-1);
|
||||||
|
var album={'link':albumlink,'name':albumname}
|
||||||
|
photoarray.push(album);
|
||||||
|
}
|
||||||
|
//print("Album"+JSON.stringify(photoarray));
|
||||||
|
callback(photoarray)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function requestFriendsPictures(link,rootwindow,callback){
|
||||||
|
// screenscraping of pictures page for given album
|
||||||
|
Helperjs.friendicaWebRequest(link,rootwindow,function(photohtml){
|
||||||
|
var photoarray=[];
|
||||||
|
var basehtml=photohtml.substring(photohtml.indexOf('<base')+12,photohtml.indexOf('/>',photohtml.indexOf('<base'))-2);
|
||||||
|
|
||||||
|
// old theme
|
||||||
|
if (photohtml.indexOf("photo-album-image-wrapper-end")>-1){ //theme 1
|
||||||
|
var arr = photohtml.split("photo-album-image-wrapper-end");}
|
||||||
|
|
||||||
|
// other themes
|
||||||
|
if (photohtml.indexOf("photo-album-wrapper")>-1){ //theme 2
|
||||||
|
var photoarea=photohtml.substring(photohtml.indexOf("photo-album-wrapper"),photohtml.indexOf("photo-album-end"))
|
||||||
|
var arr = photoarea.split("</a>");}
|
||||||
|
|
||||||
|
for (var i=0;i<arr.length-1;i++){
|
||||||
|
var photoname=arr[i].substring(arr[i].lastIndexOf('alt')+5,arr[i].lastIndexOf('title')-2);
|
||||||
|
var thumblink=arr[i].substring(arr[i].lastIndexOf('<img')+10,arr[i].lastIndexOf('alt')-2);
|
||||||
|
|
||||||
|
var imagetype=thumblink.substring(thumblink.lastIndexOf("."));
|
||||||
|
var photolink=thumblink.substring(0,thumblink.length-imagetype.length-2)+"-0"+imagetype
|
||||||
|
if(thumblink.substring(0,4)!=="http"){thumblink=basehtml+thumblink}
|
||||||
|
if(photolink.substring(0,4)!=="http"){photolink=basehtml+photolink}
|
||||||
|
var photo={'link':photolink,'name':photoname,'thumb':thumblink}
|
||||||
|
photoarray.push(photo);
|
||||||
|
}
|
||||||
|
callback(photoarray)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// CONFIG FUNCTIONS
|
||||||
|
|
||||||
|
function initDatabase(database) { // initialize the database object
|
||||||
|
var db =Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
print('initDatabase()'+database[0]+database[1]+database[2]+database[3])
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
print('... create table')
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS imageData(username TEXT,id INT, created TEXT,edited TEXT, title TEXT, desc TEXT, album TEXT,filename TEXT, type TEXT, height INT, width INT, profile INT, link TEXT,location TEXT)');
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS config(server TEXT, username TEXT, password TEXT, imagestore TEXT, maxnews INT, timerInterval INT, newsViewType TEXT,isActive INT)');
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS news(username TEXT, messagetype INT, text TEXT, created_at INT, in_reply_to_status_id INT, source TEXT, status_id INT, in_reply_to_user_id INT, geo TEXT,favorited TEXT, uid INT, statusnet_html TEXT, statusnet_conversation_id TEXT,like TEXT, dislike TEXT, attendyes TEXT,attendno TEXT, attendmaybe TEXT)');
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS contacts(username TEXT, id INT, name TEXT, screen_name TEXT, location TEXT,description TEXT, profile_image BLOB, url TEXT, protected TEXT, followers_count INT, friends_count INT, created_at TEXT, favourites_count TEXT, utc_offset TEXT, time_zone TEXT, statuses_count INT, following TEXT, verified TEXT, statusnet_blocking TEXT, notifications TEXT, statusnet_profile_url TEXT, cid INT, network TEXT, isFriend INT)');
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS groups(username TEXT, groupname TEXT, gid INT, members TEXT)');
|
||||||
|
})}
|
||||||
|
|
||||||
|
function storeConfig(database,obj) { // stores config to DB
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
print('storeConfig() for ' + obj.username)
|
||||||
|
print('database: ' + database[0]);
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
print('... check if a object exists: '+obj.username)
|
||||||
|
var result = tx.executeSql('SELECT * from config WHERE username="'+obj.username+'"');
|
||||||
|
if(result.rows.length === 1) {// use update
|
||||||
|
print(obj.username +' exists, update it');
|
||||||
|
var result2 = tx.executeSql('UPDATE config SET server="'+obj.server+'",password="'+obj.password+'", imagestore="'+obj.imagestore+'", maxnews="+obj.maxnews+", isActive=0 WHERE username="'+obj.username +'"');
|
||||||
|
var result3 = tx.executeSql('UPDATE config SET isActive=1 WHERE username !="'+obj.username +'"');
|
||||||
|
var result4 = tx.executeSql('UPDATE config SET maxnews='+obj.maxnews);
|
||||||
|
} else {// use insert print('... does not exists, create it')
|
||||||
|
var result2 = tx.executeSql('INSERT INTO config VALUES (?,?,?,?,?,?,?,?)', [obj.server, obj.username, obj.password, obj.imagestore, obj.maxnews, 0,"list",0]);
|
||||||
|
var result3 = tx.executeSql('UPDATE config SET isActive=1 WHERE username !="'+obj.username +'"');
|
||||||
|
var result4 = tx.executeSql('UPDATE config SET maxnews='+obj.maxnews);
|
||||||
|
print("Inserted");}
|
||||||
|
});}
|
||||||
|
|
||||||
|
function getServerConfig(login,rootwindow,callback){
|
||||||
|
// check server with given credentials
|
||||||
|
try {Helperjs.friendicaRequest(login,"/api/statusnet/config",rootwindow, function (obj){
|
||||||
|
var serverconfig = JSON.parse(obj);
|
||||||
|
var serverconfigString="import QtQuick 2.0; import QtQuick.Dialogs 1.2; MessageDialog{ visible: true; title:'Server';standardButtons: StandardButton.Ok;text: 'SUCCESS! \nName: "+serverconfig.site.name+"\nLanguage: "+serverconfig.site.language+
|
||||||
|
"\nEmail: "+serverconfig.site.email+"\nTimezone: "+serverconfig.site.timezone+"\nClosed: "+serverconfig.site.closed+
|
||||||
|
"\nText limit: "+serverconfig.site.textlimit+"\nShort Url length: "+serverconfig.site.shorturllength+
|
||||||
|
"\nFriendica version: "+serverconfig.site.friendica.FRIENDICA_VERSION+"\nDFRN version: "+serverconfig.site.friendica.DFRN_PROTOCOL_VERSION +
|
||||||
|
"\nDB Update version: "+serverconfig.site.friendica.DB_UPDATE_VERSION+"'}";
|
||||||
|
callback(serverconfigString);
|
||||||
|
})}
|
||||||
|
catch (e){callback (e);
|
||||||
|
}}
|
||||||
|
|
||||||
|
function readConfig(database,callback,filter,filtervalue) { // reads config
|
||||||
|
print('readConfig()')
|
||||||
|
if (filter){var where = " WHERE "+ filter +" = '" + filtervalue+"'";} else { var where="";}
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3],initDatabase(database));
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
var tables = tx.executeSql("SELECT * FROM sqlite_master WHERE type='table'");
|
||||||
|
if (tables.rows.length==0){print("no database");callback("")} else {
|
||||||
|
print('... read from database '+where)
|
||||||
|
var rs = tx.executeSql('select * from config'+where);
|
||||||
|
var rsArray=[];
|
||||||
|
if (rs.rows.length>0){
|
||||||
|
for(var i = 0; i < rs.rows.length; i++) {
|
||||||
|
rsArray.push(rs.rows.item(i))
|
||||||
|
}
|
||||||
|
var rsObject={server:rsArray[0].server,username:rsArray[0].username, password:rsArray[0].password,imagestore:rsArray[0].imagestore,maxnews:rsArray[0].maxnews,isActive:rsArray[0].isActive};
|
||||||
|
} else {
|
||||||
|
var rsObject=""
|
||||||
|
}
|
||||||
|
callback(rsObject);}}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function readActiveConfig(database){
|
||||||
|
var obj;
|
||||||
|
readConfig(database,function(config){
|
||||||
|
obj=config},"isActive", 0);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteConfig(database,userobj,callback) { // delete user data from DB
|
||||||
|
print('deleteConfig()')
|
||||||
|
if (userobj){var where = " WHERE username='"+ userobj.username+"' and server='"+userobj.server+"'";} else { return "no user selected!";}
|
||||||
|
var db=Sql.LocalStorage.openDatabaseSync(database[0],database[1],database[2],database[3]);
|
||||||
|
if(!db) { return; }
|
||||||
|
db.transaction( function(tx) {
|
||||||
|
print('... read from database '+where)
|
||||||
|
var rs = tx.executeSql('delete * from config'+where);
|
||||||
|
print(rs.toString);
|
||||||
|
callback(rs);
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtMultimedia 5.0
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Rectangle {
|
||||||
|
VideoOutput {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: localCamera
|
||||||
|
}
|
||||||
|
Camera {
|
||||||
|
id: localCamera
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
id: shotButton
|
||||||
|
width: 200; height: 75
|
||||||
|
text: "Take Photo"
|
||||||
|
onClicked: {
|
||||||
|
localCamera.imageCapture.capture();
|
||||||
|
} }
|
||||||
|
Connections {
|
||||||
|
target: localCamera.imageCapture
|
||||||
|
onImageSaved: {
|
||||||
|
photofile= imagePaths.append({"path": path})
|
||||||
|
listView.positionViewAtEnd(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: photoFromCamera
|
||||||
|
anchors.fill: parent
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: photo
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
text: "Upload"
|
||||||
|
onClicked:{
|
||||||
|
var login=Service.readActiveConfig(db);
|
||||||
|
img.src=file;
|
||||||
|
Service.Upload(login,file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,250 @@
|
||||||
|
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/3;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=="") {
|
||||||
|
filesystem.Directory=userconfig.imagestore;
|
||||||
|
filesystem.makeDir("contacts");
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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",root.login.username,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)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
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-4
|
||||||
|
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);
|
||||||
|
friendComponent.state="large"}
|
||||||
|
}
|
||||||
|
Rectangle{
|
||||||
|
id: detailsrectangle
|
||||||
|
anchors.top: namelabel.bottom
|
||||||
|
anchors.topMargin: 2*mm
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
Flickable{
|
||||||
|
id:namelabelflickable
|
||||||
|
width: root.width-10*mm
|
||||||
|
height:wrapper.height-27*mm-3
|
||||||
|
boundsBehavior:Flickable.StopAtBounds
|
||||||
|
flickableDirection:Flickable.VerticalFlick
|
||||||
|
contentWidth:width
|
||||||
|
contentHeight: namelabeltext.height
|
||||||
|
clip:true
|
||||||
|
Text{
|
||||||
|
id:namelabeltext
|
||||||
|
//anchors.top: parent.top
|
||||||
|
width: namelabelflickable.width
|
||||||
|
height: 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: namelabelflickable.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:friendsTabView.width-4*mm; text:Qt.atob(friend.name)+" (@"+friend.screen_name+")"}
|
||||||
|
PropertyChanges { target: friendComponent; z: 2 }
|
||||||
|
PropertyChanges { target: wrapper; width:friendsTabView.width-3*mm;height:friendsTabView.height-14*mm}
|
||||||
|
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 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,174 @@
|
||||||
|
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 {
|
||||||
|
y:1
|
||||||
|
color: "white"
|
||||||
|
TabView{
|
||||||
|
id:friendsTabView
|
||||||
|
// property var contacts: []
|
||||||
|
// property var groups: []
|
||||||
|
|
||||||
|
tabPosition: Qt.TopEdge
|
||||||
|
x:mm
|
||||||
|
y:mm
|
||||||
|
width: root.width-5*mm
|
||||||
|
height: root.height-10*mm
|
||||||
|
currentIndex: 0
|
||||||
|
signal friendsSignal(var username)
|
||||||
|
signal contactsSignal(var username)
|
||||||
|
signal groupsSignal(var username)
|
||||||
|
onCurrentIndexChanged:{
|
||||||
|
if (currentIndex==0){friendsSignal(root.login.username)}
|
||||||
|
else if (currentIndex==1){contactsSignal(root.login.username)}
|
||||||
|
else if (currentIndex==2){groupsSignal(root.login.username)}
|
||||||
|
}
|
||||||
|
|
||||||
|
Tab{
|
||||||
|
title: qsTr("Friends")
|
||||||
|
Rectangle{
|
||||||
|
id: friendsGridTab
|
||||||
|
function showFriends(username){
|
||||||
|
try {friendsModel.clear()} catch(e){print(e)};
|
||||||
|
Helperjs.readData(db,"contacts",username,function(friends){
|
||||||
|
for (var i=0;i<friends.length;i++){
|
||||||
|
friendsModel.append({"friend":friends[i]});
|
||||||
|
}},"isFriend",1)
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
GridView {
|
||||||
|
id: friendsView
|
||||||
|
x:mm
|
||||||
|
y:updateFriendsButton.height+mm
|
||||||
|
width:friendsGridTab.width-2*mm
|
||||||
|
height:friendsGridTab.height-updateFriendsButton.height-2*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: {
|
||||||
|
friendsTabView.friendsSignal.connect(showFriends);
|
||||||
|
showFriends(root.login.username)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Tab{
|
||||||
|
title: qsTr("Other Contacts")
|
||||||
|
|
||||||
|
Rectangle{
|
||||||
|
id: contactsGridTab
|
||||||
|
function showContacts(username){
|
||||||
|
try {contactsModel.clear()} catch(e){print(e)};
|
||||||
|
Helperjs.readData(db, "contacts",root.login.username,function(friendsobject){
|
||||||
|
for (var j=0;j<friendsobject.length;j++){
|
||||||
|
contactsModel.append({"friend":friendsobject[j]});
|
||||||
|
}
|
||||||
|
},"isFriend",0)}
|
||||||
|
|
||||||
|
GridView {
|
||||||
|
id: contactsView
|
||||||
|
x:mm
|
||||||
|
y:mm
|
||||||
|
width:contactsGridTab.width-2*mm
|
||||||
|
height:contactsGridTab.height-2*mm
|
||||||
|
clip: true
|
||||||
|
cellHeight: 16*mm
|
||||||
|
cellWidth: 17*mm
|
||||||
|
add: Transition {
|
||||||
|
NumberAnimation { properties: "x,y"; from: 300; duration: 1000 }
|
||||||
|
}
|
||||||
|
model: contactsModel
|
||||||
|
delegate: FriendComponent { }
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel{id: contactsModel}
|
||||||
|
Component.onCompleted: {
|
||||||
|
friendsTabView.contactsSignal.connect(showContacts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tab{
|
||||||
|
title: qsTr("Groups")
|
||||||
|
Rectangle{
|
||||||
|
id: groupsGridTab
|
||||||
|
function showGroups(username){
|
||||||
|
try {groupsModel.clear()} catch(e){print(e)};
|
||||||
|
print("showGroups"+username);
|
||||||
|
Helperjs.readData(db, "groups",root.login.username,function(groupsobject){
|
||||||
|
for (var j=0;j<groupsobject.length;j++){
|
||||||
|
groupsModel.append({"group":groupsobject[j]});
|
||||||
|
}})}
|
||||||
|
Button {
|
||||||
|
id: updateGroupsButton
|
||||||
|
text: qsTr("Update")
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
onClicked: {
|
||||||
|
print("Update groups");
|
||||||
|
Newsjs.requestGroups(root.login,root.db,root,function(){
|
||||||
|
showGroups(root.login.username)})}
|
||||||
|
}
|
||||||
|
GridView {
|
||||||
|
id: groupsView
|
||||||
|
x:mm
|
||||||
|
y:updateGroupsButton.height+mm
|
||||||
|
width:groupsGridTab.width-2*mm
|
||||||
|
height:groupsGridTab.height-updateGroupsButton.height-2*mm
|
||||||
|
clip: true
|
||||||
|
cellHeight: 16*mm
|
||||||
|
cellWidth: 17*mm
|
||||||
|
add: Transition {
|
||||||
|
NumberAnimation { properties: "x,y"; from: 300; duration: 1000 }
|
||||||
|
}
|
||||||
|
model: groupsModel
|
||||||
|
delegate: GroupComponent { }
|
||||||
|
}
|
||||||
|
ListModel{
|
||||||
|
id: groupsModel
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
friendsTabView.groupsSignal.connect(showGroups);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
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: groupComponent
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: wrapper
|
||||||
|
width: 16*mm
|
||||||
|
height: 15*mm
|
||||||
|
border.color: "grey"
|
||||||
|
color:"white"
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: namelabel
|
||||||
|
x: 1
|
||||||
|
width: wrapper.width-2
|
||||||
|
height: 3*mm
|
||||||
|
text: group.groupname
|
||||||
|
|
||||||
|
color: "#303030"
|
||||||
|
font.pixelSize: 3*mm
|
||||||
|
anchors.centerIn:parent
|
||||||
|
}
|
||||||
|
Button{
|
||||||
|
id:infobutton
|
||||||
|
width: 5*mm
|
||||||
|
height: 5*mm
|
||||||
|
text:"?"
|
||||||
|
anchors.top: namelabel.bottom;anchors.topMargin: 3
|
||||||
|
onClicked:{
|
||||||
|
print("State: "+ groupComponent.state+groupView.contentY);
|
||||||
|
groupComponent.state="large"}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rectangle{
|
||||||
|
id: detailsrectangle
|
||||||
|
anchors.top: infobutton.bottom
|
||||||
|
anchors.topMargin: 2*mm
|
||||||
|
opacity: 0
|
||||||
|
|
||||||
|
Component { id:footerComponent
|
||||||
|
Rectangle{
|
||||||
|
border.color: "#EEEEEE"
|
||||||
|
border.width: 1
|
||||||
|
width:parent.width
|
||||||
|
height:6*mm
|
||||||
|
Text{
|
||||||
|
font.pixelSize: 3*mm
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text:qsTr("+")
|
||||||
|
}
|
||||||
|
MouseArea{anchors.fill:parent
|
||||||
|
onClicked:{var contactitems="";
|
||||||
|
readData(db,"contacts",root.login.username, function(contacts){for (var i=0;i<contacts.length;i++){
|
||||||
|
contactitems=contactitems+"MenuItem{text:'"+contacts[i].screen_name+"'; onTriggered: groupModel.append(' @"+contacts[i]+"')}"
|
||||||
|
}},"isFriend",0)
|
||||||
|
var menuString="import QtQuick.Controls 1.4; Menu {"+contactitems+"}";
|
||||||
|
print("menustring: "+menuString);
|
||||||
|
var contactlistObject=Qt.createQmlObject(menuString,messageSend,"contactmenuOutput");
|
||||||
|
contactlistObject.popup();
|
||||||
|
Newsjs.addToGroup
|
||||||
|
}}}}
|
||||||
|
|
||||||
|
Component { id:groupMember
|
||||||
|
Rectangle{
|
||||||
|
border.color: "#EEEEEE"
|
||||||
|
border.width: 1
|
||||||
|
width:parent.width
|
||||||
|
height:6*mm
|
||||||
|
Text{
|
||||||
|
font.pixelSize: 3*mm
|
||||||
|
anchors.left: parent.left
|
||||||
|
text:groupmember.screen_name
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
ListView{
|
||||||
|
id:namelabeltext
|
||||||
|
anchors.top: parent.top
|
||||||
|
width: root.width-10*mm
|
||||||
|
height:wrapper.height-20*mm
|
||||||
|
clip: true
|
||||||
|
spacing: 0
|
||||||
|
footer: footerComponent
|
||||||
|
model: groupModel
|
||||||
|
delegate: groupMember
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel{id: groupModel}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
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 {
|
||||||
|
y:1
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,286 @@
|
||||||
|
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+friendicaActivities.height+4*mm),profileImage.height+user_name.height+mm)
|
||||||
|
|
||||||
|
// property var friendica_activities
|
||||||
|
property string conversation_id: ""
|
||||||
|
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*mm
|
||||||
|
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{id: friendicaActivities
|
||||||
|
spacing:mm
|
||||||
|
Label{color: "grey"
|
||||||
|
font.pixelSize: 1.5*mm
|
||||||
|
text: friendica_activities.likeText
|
||||||
|
}
|
||||||
|
Label{color: "grey"
|
||||||
|
font.pixelSize: 1.5*mm
|
||||||
|
text: friendica_activities.dislikeText
|
||||||
|
}
|
||||||
|
Label{color: "grey"
|
||||||
|
font.pixelSize: 1.5*mm
|
||||||
|
text: friendica_activities.attendyesText
|
||||||
|
}
|
||||||
|
Label{color: "grey"
|
||||||
|
font.pixelSize: 1.5*mm
|
||||||
|
text: friendica_activities.attendnoText
|
||||||
|
}
|
||||||
|
Label{color: "grey"
|
||||||
|
font.pixelSize: 1.5*mm
|
||||||
|
text: friendica_activities.attendmaybeText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Row {
|
||||||
|
CheckBox{id:likeCheckbox
|
||||||
|
height:3*mm
|
||||||
|
width:8*mm
|
||||||
|
checked:(newsitemobject.liked==1)?true:false
|
||||||
|
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
|
||||||
|
checked: (newsitemobject.disliked==1)?true:false
|
||||||
|
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);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
|
@ -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) }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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("Source: "+source+"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
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
}}}
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
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
|
||||||
|
y:1
|
||||||
|
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].id,root.db,fotorectangle);
|
||||||
|
newImagesProgress.visible=true //download first image
|
||||||
|
}}
|
||||||
|
onCurrentImageNoChanged:{
|
||||||
|
if(currentImageNo<newImages.length){Service.dataRequest(root.login,newImages[currentImageNo].id,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);}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Dialogs 1.2
|
||||||
|
import QtQuick.Controls 1.2
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Rectangle{
|
||||||
|
property string photofile:"../images/Update.png"
|
||||||
|
color: "grey"
|
||||||
|
|
||||||
|
FileDialog {
|
||||||
|
id: fileDialog
|
||||||
|
title: "Please choose a file"
|
||||||
|
folder: shortcuts.pictures
|
||||||
|
selectMultiple: true
|
||||||
|
onAccepted: {
|
||||||
|
photofile=fileDialog.fileUrls[0];
|
||||||
|
console.log("You chose: " + fileDialog.fileUrls)
|
||||||
|
// img.src=file;
|
||||||
|
}
|
||||||
|
onRejected: {
|
||||||
|
console.log("Canceled")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Component.onCompleted: {fileDialog.open()}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: photoFromFilesystem
|
||||||
|
x: 20;y:50
|
||||||
|
height: 200
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: photofile
|
||||||
|
|
||||||
|
onStatusChanged:{
|
||||||
|
if (photoFromFilesystem.status == Image.Ready) {
|
||||||
|
Layoutjs.showFriends(db)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
text: "Upload"
|
||||||
|
onClicked:{
|
||||||
|
var login=Service.readActiveConfig(db);
|
||||||
|
Service.uploadMedia(login,photofile, function(returnvalue){print("Upload return"+returnvalue)})
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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",root.login.username,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
|
|
@ -0,0 +1,112 @@
|
||||||
|
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: 400//Screen.desktopAvailableWidth
|
||||||
|
height: 400// 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)
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
print("Current contact"+JSON.stringify(newContacts[currentContact]));
|
||||||
|
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
|
||||||
|
try{var imagename=login.imagestore+"contacts/"+contact.screen_name+".jpg";
|
||||||
|
var component=Qt.createComponent("qrc:/qml/PhotoPlaceholder.qml");
|
||||||
|
print("imageName "+imagename+" source "+ contact.profile_image_url)
|
||||||
|
var sprite = component.createObject(root, {"fillMode": "Image.PreserveAspectFit","x":root.width,"y":50,"imageName":imagename,"source": contact.profile_image_url,"downloadtype":"contact"});} catch(e){print("Fehler beim Profilbild"+e)}
|
||||||
|
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("Contacts")
|
||||||
|
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…
Reference in New Issue