Skip to content

Commit

Permalink
Feature/dropbox (#185)
Browse files Browse the repository at this point in the history
* kick off dropbox

* navigate to success view after connecting to dropbox

* some tweaks after merge conflicts

* add dropbox database methods

* finish server connection

* fix success navigation bug

* get env vars from tellaConfig file

* fix typo in dropboxDatabase

* change server to DropboxServer in dropboxData

* add localizable and move some strings to dropbox constants

* change db versions

* move setupDropbox function to dropbox repository

* add empty message on successConnectionButtonContent

* remove unused repository vars on serverSelectionView

* merge dropboxAuthVM and dropboxServerVM

* merge driveServerVM and driveAuthVM

* add rootViewController to UIApplication extensions

* Refactor Dropbox

* change environment to ObservedObject in serverSelectionView

* handle result of add dropbox server

* change viewModelState to bool in gDrive server

* kickoff report submission

* fixes after merging

* add dropbox db methods

* add outbox details view

* add updateReportStatus to dropbox methods

* test file submission

* add combine to dropbox report submission

* implement submitted dropbox reports

* add navigate to submitDetails after dropbox submission

* fix database issue

* update dropbox progress bar

* save dropbox folder id in report

* clear cancellables during pause and resume

* implement chunk submission

* change submitted to pause while filtering files to upload in dropbox outboxVM

* resume chunk submission

* unify dropbox upload

* move error handling into a separate function in dropbox submission

* add APIError to dropbox repository

* add logic for re authenticate dropbox account

* handle multiple dropbox errors

* move dropbox error methods to a separate function

* some fixes on dropbox error parser

* refactor upload files params

* handle network loss

* fix issue with duplicate folders

* add error localization for dropbox

* remove offset from instance vault file and use bytesSent instead

* handle error on handleURLRedirect

* make dropboxErrorParser an extension of APIError

* remove unused offset attr

* remove old comment

* move report creation logic to repository

* remove static method from dropbox APIError extension

* fix icon when showing re-connect warning

* add prefixedWithSlash extension

* fix network connectivity loss

* refactor dropbox submit report params

* Refactor database return type and add delete submitted reports to dropbox and gDrive

* Refactor uploading a report functions

* Refactor the report uploading functions

* Delete unused code

* Refactor uploadFileInChunks

* Refactor uploadFileInChunks function

* Refactor uploadFileInChunks function

* Refactor uploadFileInChunks function

* Refactor uploadFileInChunks function

* Refactor uploadFileInChunks function

* Refactor uploadFileInChunks function

* Fix delete submitted reports

* Draft view:  Fill report

* Draft view:  validate report

* Fix pause/resume bugs

* Handle pause/resume

* Refactor errors

* Refactor error class

* Improve code

* Remov double push to submitted report

* Replace upload request with task / remove initial state / improve code

* Fix handle network loss

* Update TellaDAtabase

* Move setupDropbox to AppDelegate

* Move signOut action to viewmodel

* Load the VaultFile to URL asynchronously

* Rename functions

* Draft View: Add validator/error to title

* Update submitted list title and update correct dropbox icon

* Delete unused error parameter

* Delete unused "== true" to check boolean type

* Simplify if let sentence

* Fix typo

* update subject in Dropbox repo

* Unify delete server return type

* unify pause function in DropboxRepository

* rename submit methods

* Fix errors

* Update dropbox functions name

* Delete unused folderId param in server table

* Delete performSubmission function

* Refactor converting Reportfile to ReportVaultFiles function

* Nextcloud report : Load files asynchronously

* Fix folder name error in create folder when adding a connection

* Remove unused ReportFileProtocol

* Fix connection expired for reports

* Fix showing infiniy toast issue

* remove unused code

* Remove unused code

* Refactor initSubmission

* Moving DropboxReportFile and NextcloudReportFile to ReportFileExtension

* Correct the folders references

* Centralise updateCurrentFile function

* Centralise updateCurrentFile function

* Centralise checkAllFilesAreUploaded function

* Centralise handleSubmitReportCompletion function

* Delete unused code

* Fix uploading a small file

* Fix uploading bugs

* Update submitted status instead of uploaded status

* Update  uploadTasks dictionary with upload task

* Fix Tella web login view

---------

Co-authored-by: gus valbuena <[email protected]>
Co-authored-by: rimKtarii <[email protected]>
Co-authored-by: Dhekra Rouatbi <[email protected]>
Co-authored-by: dhekra-rouatbi <[email protected]>
  • Loading branch information
5 people authored Oct 31, 2024
1 parent f2edcb5 commit 71d4982
Show file tree
Hide file tree
Showing 96 changed files with 3,060 additions and 664 deletions.
1 change: 1 addition & 0 deletions Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ target 'Tella' do
pod 'Mantis', '~> 2.21.0'
pod 'GoogleSignIn'
pod 'GoogleAPIClientForREST/Drive'
pod 'SwiftyDropbox'

target 'TellaTests' do
inherit! :search_paths
Expand Down
248 changes: 201 additions & 47 deletions Tella.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions Tella/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import Foundation
import UIKit
import SwiftyDropbox

class AppDelegate: NSObject, UIApplicationDelegate {

Expand All @@ -14,6 +15,9 @@ class AppDelegate: NSObject, UIApplicationDelegate {

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
AppDelegate.instance = self

setupDropbox()

return true
}

Expand All @@ -25,4 +29,12 @@ class AppDelegate: NSObject, UIApplicationDelegate {
backgroundSessionCompletionHandler = completionHandler
shouldHandleTimeout = true
}

private func setupDropbox() {
guard let dropboxAppKey = ConfigurationManager.getValue(DropboxAuthConstants.dropboxAppKey) else {
debugLog("Dropbox App Key not found")
return
}
DropboxClientsManager.setupWithAppKey(dropboxAppKey)
}
}
51 changes: 38 additions & 13 deletions Tella/Components/TextfieldView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,27 @@ enum FieldType {
case text
case password
case code
case folderName
}

struct TextfieldView : View {

@Binding var fieldContent : String
@State private var pfieldContent : String = ""

@Binding var isValid : Bool
@Binding var shouldShowError : Bool

var errorMessage : String?
var validationErrorMessage : String?
var fieldType : FieldType
var placeholder : String = ""
var shouldShowTitle : Bool = false
var shouldValidateOnChange : Bool = false
var onCommit : (() -> Void)? = ({})

@State private var shouldShowPassword : Bool = false
@State private var shouldShowErrorOnChange : Bool = false

private var keyboardType: UIKeyboardType {
switch fieldType {
Expand All @@ -40,6 +45,19 @@ struct TextfieldView : View {
return . default
}
}

private var shouldShowErrorTextOnChange: Bool {
(shouldShowErrorOnChange && !pfieldContent.isEmpty)
}

private var formattedErrorMessage: String? {
if shouldShowError {
return errorMessage
} else if shouldShowErrorTextOnChange {
return validationErrorMessage
}
return nil
}

var body: some View {

Expand All @@ -54,7 +72,7 @@ struct TextfieldView : View {
.font(.custom(Styles.Fonts.regularFontName, size: 14))
.frame(maxWidth: .infinity,alignment: .leading)
.contentShape(Rectangle())

.foregroundColor(fieldContent.isEmpty ? .white : .white.opacity(0.8))
.scaleEffect(fieldContent.isEmpty ? 1 : 0.88, anchor: .leading)
.transaction { transaction in
Expand All @@ -64,7 +82,7 @@ struct TextfieldView : View {

}
}

// Textfield
if fieldType == .password || fieldType == .code {
passwordTextfieldView
Expand All @@ -78,6 +96,7 @@ struct TextfieldView : View {

// Error message
errorMessageView
Spacer()
}
}

Expand Down Expand Up @@ -117,7 +136,7 @@ struct TextfieldView : View {
})
.textFieldStyle(TextfieldStyle(shouldShowError: shouldShowError, keyboardType: keyboardType))
.frame( height: 22)

Spacer()
.frame(width: 10)

Expand All @@ -134,20 +153,19 @@ struct TextfieldView : View {
var dividerView : some View {
Divider()
.frame(height: 1)
.background(shouldShowError ? Color(UIColor(hexValue: 0xFF2D2D)) : Color.white)
.background(shouldShowError || shouldShowErrorTextOnChange ? Color(UIColor(hexValue: 0xFF2D2D)) : Color.white)
}

@ViewBuilder
var errorMessageView : some View {
if let errorMessage = errorMessage, shouldShowError == true {
Text(errorMessage)
if let formattedErrorMessage {
Text(formattedErrorMessage)
.font(.custom(Styles.Fonts.regularFontName, size: 12))
.foregroundColor(Color(UIColor(hexValue: 0xFF2D2D)))
.frame(maxWidth: .infinity, alignment: .leading)
}

}

private func validateField(value:String) {

switch fieldType {
Expand All @@ -165,18 +183,25 @@ struct TextfieldView : View {

case .code:
self.isValid = value.codeValidator()

case .folderName:
self.isValid = value.folderNameValidator()
}

if shouldValidateOnChange {
shouldShowErrorOnChange = !self.isValid
} else {
self.shouldShowError = false
}
self.shouldShowError = false
}

}

struct TextfieldStyle: TextFieldStyle {

var shouldShowError : Bool = false

var keyboardType : UIKeyboardType = .default

func _body(configuration: TextField<Self._Label>) -> some View {
configuration
.font(.custom(Styles.Fonts.regularFontName, size: 14))
Expand Down
2 changes: 1 addition & 1 deletion Tella/Components/UnderlinedTextEditorView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ struct UnderlinedTextEditorView : View {

@ViewBuilder
var errorMessageView : some View {
if let errorMessage = errorMessage, shouldShowError == true {
if let errorMessage, shouldShowError {
Text(errorMessage)
.font(.custom(Styles.Fonts.regularFontName, size: 12))
.foregroundColor(Color(UIColor(hexValue: 0xFF2D2D)))
Expand Down
8 changes: 7 additions & 1 deletion Tella/Data/Database/Common/DatabaseConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct D {

/* DATABASE VERSION */

static let databaseVersion = 7
static let databaseVersion = 8

/* DEFAULT TYPES FOR DATABASE */
// MARK: - DEFAULT TYPES FOR DATABASE
Expand All @@ -40,6 +40,9 @@ struct D {
static let tNextcloudServer = "t_nextcloud_server"
static let tNextcloudReport = "t_nextcloud_report"
static let tNextcloudInstanceVaultFile = "t_nextcloud_instance_vault_file"
static let tDropboxServer = "t_dropbox_server"
static let tDropboxReport = "t_dropbox_report"
static let tDropboxInstanceVaultFile = "t_dropbox_instance_vault_file"

/* DATABASE COLUMNS */
// MARK: - DATABASE COLUMNS
Expand Down Expand Up @@ -107,6 +110,9 @@ struct D {
static let cUserId = "c_user_id"
static let cRemoteReportStatus = "c_remote_report_status"
static let cChunkFiles = "c_chunk_files"

//dropbox
static let cSessionId = "c_session_id"
}


74 changes: 74 additions & 0 deletions Tella/Data/Database/Dropbox/DropboxData.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// DropboxData.swift
// Tella
//
// Created by gus valbuena on 9/9/24.
// Copyright © 2024 HORIZONTAL. All rights reserved.
//

import Foundation

extension TellaData {

///ADD
func addDropboxReport(report: DropboxReport) -> Result<Int, Error> {
database.addDropboxReport(report: report)
}

/// GET
func getDropboxServers() -> [DropboxServer] {
self.database.getDropboxServers()
}

func getDraftDropboxReports() -> [DropboxReport] {
return self.database.getDropboxReports(reportStatus: [.draft])
}

func getOutboxedDropboxReports() -> [DropboxReport] {
return self.database.getOutboxReports(tableName: D.tDropboxReport)
}

func getSubmittedDropboxReports() -> [DropboxReport] {
return self.database.getDropboxReports(reportStatus: [.submitted])
}

func getDropboxReport(id: Int?) -> DropboxReport? {
guard let id else { return nil }
return self.database.getDropboxReport(id: id)
}

/// UPDATE
func updateDropboxReport(report: DropboxReport) -> Result<Void, Error> {
self.database.updateDropboxReport(report: report)
}

@discardableResult
func updateDropboxReportStatus(reportId: Int, status: ReportStatus) -> Result<Void, Error> {
self.database.updateDropboxReportStatus(idReport: reportId, status: status)
}

@discardableResult
func updateDropboxReportWithoutFiles(report: DropboxReport) -> Result<Void,Error> {
database.updateDropboxReportWithoutFiles(report: report)
}

@discardableResult
func updateDropboxReportFile(file: DropboxReportFile) -> Result<Void, Error> {
self.database.updateDropboxReportFile(reportFile: file)
}

/// DELETE
func deleteDropboxReport(reportId: Int?) -> Result<Void, Error> {
let deleteDropboxReportResult = self.database.deleteDropboxReport(reportId: reportId)
shouldReloadDropboxReports.send(true)
return deleteDropboxReportResult
}

@discardableResult
func deleteDropboxSubmittedReports() -> Result<Void,Error> {
let deleteSubmittedReportResult = database.deleteDropboxSubmittedReports()
shouldReloadDropboxReports.send(true)
return deleteSubmittedReportResult
}

}
Loading

0 comments on commit 71d4982

Please sign in to comment.