Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize MailModel.folders as empty Map #7967

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app-android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,23 @@ android {
buildTypes {
debug {
resValue("string", "package_name", "de.tutao.tutanota.debug")
resValue("string", "account_type", "de.tutao.tutanota.debug")
manifestPlaceholders = [contentProviderAuthority: 'de.tutao.fileprovider.debug']
applicationIdSuffix ".debug"
jniDebuggable true
}
release {
minifyEnabled true
resValue("string", "package_name", "de.tutao.tutanota")
resValue("string", "account_type", "de.tutao.tutanota")
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
manifestPlaceholders = [contentProviderAuthority: 'de.tutao.fileprovider']
}
releaseTest {
initWith release
minifyEnabled true
resValue("string", "package_name", "de.tutao.tutanota.test")
resValue("string", "account_type", "de.tutao.tutanota.test")
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
manifestPlaceholders = [contentProviderAuthority: 'de.tutao.fileprovider.test']
applicationIdSuffix ".test"
Expand Down
3 changes: 0 additions & 3 deletions app-android/app/src/debugDist/res/values/strings.xml

This file was deleted.

11 changes: 7 additions & 4 deletions app-android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -161,29 +161,32 @@


<service
android:name="de.tutao.tutashared.credentials.AccountManagerAuthenticatorService"
android:name="de.tutao.tutashared.credentials.AccountAuthenticatorService"
android:exported="false">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator"/>
</intent-filter>

<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator"/>
android:resource="@xml/account_authenticator"/>
</service>

<service
android:name=".StubSyncService"
android:exported="false"
android:exported="true"
android:process=":sync">
<intent-filter>
<action android:name="android.content.SyncAdapter"/>
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/syncadapter"/>
<meta-data
android:name="android.provider.CONTACTS_STRUCTURE"
android:resource="@xml/contacts"/>
</service>


<receiver
android:name=".push.BootBroadcastReceiver"
android:exported="false">
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,11 @@ class AndroidThemeFacade(
// So for Android M and above we alternate between white and dark status bar colors and
// we change lightStatusBar flag accordingly.
activity.window.statusBarColor = statusBarColor
if (isStatusBarLight) {
windowInsetController.isAppearanceLightStatusBars = true
}
windowInsetController.isAppearanceLightStatusBars = isStatusBarLight
}

private fun getColor(theme: Map<String, String>, key: String): String =
theme[key] ?: LIGHT_FALLBACK_THEME[key] ?: "#FFFFFF"
theme[key] ?: LIGHT_FALLBACK_THEME[key] ?: "#FFFFFF"

override suspend fun getThemes(): List<Map<String, String>> {
return this.themes
Expand Down
20 changes: 10 additions & 10 deletions app-android/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<resources>
<string name="app_name" translatable="false">Tuta</string>
<string name="reminder_label">Reminder</string>
<string name="pushNewMail_msg">New email received.</string>
<string name="notificationSync_msg">Synchronizing notifications</string>
<string name="scheduleAlarmError_msg">Could not set up an alarm. Please update the application.</string>
<string name="wantToSendReport_msg">Something unexpected went wrong. Do you want to send an error report? You can add a message to help us fix this error.</string>
<string name="downloadCompleted_msg">Download completed</string>
<string name="unlockCredentials_action">Unlock credentials</string>
<string name="delete_action">Delete</string>
<string name="markRead_action">Mark read</string>
<string name="app_name" translatable="false">Tuta</string>
<string name="reminder_label">Reminder</string>
<string name="pushNewMail_msg">New email received.</string>
<string name="notificationSync_msg">Synchronizing notifications</string>
<string name="scheduleAlarmError_msg">Could not set up an alarm. Please update the application.</string>
<string name="wantToSendReport_msg">Something unexpected went wrong. Do you want to send an error report? You can add a message to help us fix this error.</string>
<string name="downloadCompleted_msg">Download completed</string>
<string name="unlockCredentials_action">Unlock credentials</string>
<string name="delete_action">Delete</string>
<string name="markRead_action">Mark read</string>
</resources>
5 changes: 5 additions & 0 deletions app-android/app/src/main/res/xml/account_authenticator.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="@string/account_type"
android:icon="@mipmap/ic_logo_round"
android:label="@string/app_name"
android:smallIcon="@mipmap/ic_logo_round"/>
7 changes: 0 additions & 7 deletions app-android/app/src/main/res/xml/authenticator.xml

This file was deleted.

61 changes: 61 additions & 0 deletions app-android/app/src/main/res/xml/contacts.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- The base valid EditSchema must contain "name" and "photo" DataKinds -->
<!-- An invalid EditSchema will result in Tuta not being detected as a contact provider -->
<ContactsAccountType>
<EditSchema>
<DataKind kind="photo" maxOccurs="1"/>
<DataKind kind="name"
maxOccurs="1"
supportsDisplayName="false"
supportsPrefix="true"
supportsMiddleName="true"
supportsSuffix="true"
supportsPhoneticGivenName="true"
supportsPhoneticMiddleName="true"
supportsPhoneticFamilyName="true"
/>
<DataKind kind="phone">
<Type type="home"/>
<Type type="work"/>
<Type type="mobile"/>
<Type type="other_fax"/>
<Type type="other"/>
<Type type="custom"/>
</DataKind>
<DataKind kind="email">
<Type type="home"/>
<Type type="work"/>
<Type type="other"/>
<Type type="custom"/>
</DataKind>
<DataKind kind="nickname" maxOccurs="1"/>
<DataKind kind="im">
<Type type="custom"/>
</DataKind>
<DataKind kind="postal" needsStructured="false">
<Type type="home"/>
<Type type="work"/>
<Type type="other"/>
<Type type="custom"/>
</DataKind>
<DataKind kind="organization" maxOccurs="1"/>
<DataKind kind="website"/>
<DataKind kind="note" maxOccurs="1"/>
<DataKind kind="event" dateWithTime="false">
<Type type="birthday" maxOccurs="1" yearOptional="true"/>
</DataKind>
<DataKind kind="relationship">
<Type type="parent"/>
<Type type="brother"/>
<Type type="sister"/>
<Type type="child"/>
<Type type="friend"/>
<Type type="relative"/>
<Type type="spouse"/>
<Type type="partner"/>
<Type type="assistant"/>
<Type type="manager"/>
<Type type="custom"/>
</DataKind>
</EditSchema>
</ContactsAccountType>
8 changes: 4 additions & 4 deletions app-android/app/src/main/res/xml/syncadapter.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
<sync-adapter
xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="com.android.contacts"
android:accountType="@string/package_name"
android:userVisible="false"
android:supportsUploading="false"
android:accountType="@string/account_type"
android:userVisible="true"
android:supportsUploading="true"
android:allowParallelSyncs="false"
android:isAlwaysSyncable="true"
/>
/>
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ package de.tutao.tutashared.credentials

import android.app.Service
import android.content.Intent

import android.os.IBinder


class AccountManagerAuthenticatorService : Service() {
class AccountAuthenticatorService : Service() {
private var authenticator: AccountManagerAuthenticator? = null

override fun onCreate() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package de.tutao.tutashared.credentials
import android.accounts.*
import android.content.Context
import android.os.Bundle
import android.util.Log

class AccountManagerAuthenticator(context: Context) : AbstractAccountAuthenticator(context) {
private val context: Context
Expand All @@ -16,6 +17,7 @@ class AccountManagerAuthenticator(context: Context) : AbstractAccountAuthenticat
authTokenType: String,
requiredFeatures: Array<String>,
options: Bundle): Bundle? {
Log.d("Sync", "AccountManagerAuthenticator addAccount")
return null
}

Expand Down
23 changes: 9 additions & 14 deletions app-ios/tutanota/Sources/Files/FileChooser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ class TUTFileChooser: NSObject, UIImagePickerControllerDelegate, UINavigationCon
private var sourceController: UIViewController
private var cameraImage: UIImage
private var photoLibImage: UIImage
private var attachmentTypeMenu: UIDocumentMenuViewController?
private var imagePickerController: UIImagePickerController
private var supportedUTIs: [String]
private var resultHandler: ResponseCallback<[String]>?
private var popOverPresentationController: UIPopoverPresentationController?

init(viewController: UIViewController) {
supportedUTIs = ["public.content", "public.archive", "public.data"]
Expand All @@ -33,27 +31,24 @@ class TUTFileChooser: NSObject, UIImagePickerControllerDelegate, UINavigationCon
previousHandler(.success([]))
}

var attachmentTypeMenu: UIDocumentMenuViewController?
var filePicker: UIDocumentPickerViewController?

if isFileOnly {
filePicker = UIDocumentPickerViewController(forOpeningContentTypes: [UTType.content, UTType.archive, UTType.data], asCopy: true)
filePicker!.delegate = self
} else {
self.attachmentTypeMenu = UIDocumentMenuViewController(documentTypes: supportedUTIs, in: UIDocumentPickerMode.import)
self.attachmentTypeMenu!.delegate = self
attachmentTypeMenu = UIDocumentMenuViewController(documentTypes: supportedUTIs, in: UIDocumentPickerMode.import)
attachmentTypeMenu!.popoverPresentationController?.sourceView = sourceController.view
attachmentTypeMenu!.popoverPresentationController?.sourceRect = anchorRect
attachmentTypeMenu!.delegate = self
}

// add menu item for selecting images from photo library.
// according to developer documentation check if the source type is available first https://developer.apple.com/reference/uikit/uiimagepickercontroller
if !isFileOnly && UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum) {
if UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad {
filePicker?.modalPresentationStyle = .popover
popOverPresentationController = filePicker?.popoverPresentationController
popOverPresentationController?.permittedArrowDirections = [.up, .down]
popOverPresentationController?.sourceView = sourceController.view
popOverPresentationController?.sourceRect = anchorRect
}
let photosLabel = translate("TutaoChoosePhotosAction", default: "Photos")
self.attachmentTypeMenu!
attachmentTypeMenu!
.addOption(
withTitle: photosLabel,
image: photoLibImage,
Expand Down Expand Up @@ -87,12 +82,12 @@ class TUTFileChooser: NSObject, UIImagePickerControllerDelegate, UINavigationCon
let cameraLabel = translate("TutaoShowCameraAction", default: "Camera")

// capture the weak reference to avoid reference cycle
self.attachmentTypeMenu!.addOption(withTitle: cameraLabel, image: cameraImage, order: .first) { [weak self] in self?.openCamera() }
attachmentTypeMenu!.addOption(withTitle: cameraLabel, image: cameraImage, order: .first) { [weak self] in self?.openCamera() }
}

return try await withCheckedThrowingContinuation { continuation in
resultHandler = continuation.resume(with:)
sourceController.present((isFileOnly ? filePicker : self.attachmentTypeMenu)!, animated: true, completion: nil)
sourceController.present((isFileOnly ? filePicker : attachmentTypeMenu)!, animated: true, completion: nil)
}
}

Expand Down
4,559 changes: 4,558 additions & 1 deletion resources/images/onboarding-wizard/congratulations.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 17 additions & 6 deletions src/calendar-app/calendarLocator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import { InfoMessageHandler } from "../common/gui/InfoMessageHandler.js"
import { NativeInterfaces } from "../common/native/main/NativeInterfaceFactory.js"
import { EntropyFacade } from "../common/api/worker/facades/EntropyFacade.js"
import { SqlCipherFacade } from "../common/native/common/generatedipc/SqlCipherFacade.js"
import { assertNotNull, defer, DeferredObject, lazy, lazyAsync, LazyLoaded, lazyMemoized, noOp, ofClass } from "@tutao/tutanota-utils"
import { assertNotNull, defer, DeferredObject, lazy, lazyAsync, LazyLoaded, lazyMemoized, noOp } from "@tutao/tutanota-utils"
import { RecipientsModel } from "../common/api/main/RecipientsModel.js"
import { NoZoneDateProvider } from "../common/api/common/utils/NoZoneDateProvider.js"
import { CalendarEvent, CalendarEventAttendee, Contact, Mail, MailboxProperties } from "../common/api/entities/tutanota/TypeRefs.js"
Expand All @@ -64,8 +64,7 @@ import { CalendarViewModel } from "./calendar/view/CalendarViewModel.js"
import { CalendarEventModel, CalendarOperation } from "./calendar/gui/eventeditor-model/CalendarEventModel.js"
import { CalendarEventsRepository } from "../common/calendar/date/CalendarEventsRepository.js"
import { showProgressDialog } from "../common/gui/dialogs/ProgressDialog.js"
import { RecipientsSearchModel } from "../common/misc/RecipientsSearchModel.js"
import { PermissionError } from "../common/api/common/error/PermissionError.js"
import { ContactSuggestionProvider, RecipientsSearchModel } from "../common/misc/RecipientsSearchModel.js"
import { NativeInterfaceMain } from "../common/native/main/NativeInterfaceMain.js"
import { NativeFileApp } from "../common/native/common/FileApp.js"
import { NativePushServiceApp } from "../common/native/main/NativePushServiceApp.js"
Expand Down Expand Up @@ -112,6 +111,7 @@ import { DbError } from "../common/api/common/error/DbError.js"
import { WorkerRandomizer } from "../common/api/worker/workerInterfaces.js"
import { lang } from "../common/misc/LanguageViewModel.js"
import type { CalendarContactPreviewViewModel } from "./calendar/gui/eventpopup/CalendarContactPreviewViewModel.js"
import { ContactSuggestion } from "../common/native/common/generatedipc/ContactSuggestion"

assertMainOrNode()

Expand Down Expand Up @@ -364,12 +364,23 @@ class CalendarLocator {

async recipientsSearchModel(): Promise<RecipientsSearchModel> {
const { RecipientsSearchModel } = await import("../common/misc/RecipientsSearchModel.js")
const suggestionsProvider = isApp()
? (query: string) => this.mobileContactsFacade.findSuggestions(query).catch(ofClass(PermissionError, () => []))
: null
const suggestionsProvider = await this.contactSuggestionProvider()
return new RecipientsSearchModel(await this.recipientsModel(), this.contactModel, suggestionsProvider, this.entityClient)
}

private async contactSuggestionProvider(): Promise<ContactSuggestionProvider> {
if (isApp()) {
const { MobileContactSuggestionProvider } = await import("../common/native/main/MobileContactSuggestionProvider.js")
return new MobileContactSuggestionProvider(this.mobileContactsFacade)
} else {
return {
async getContactSuggestions(_query: String): Promise<readonly ContactSuggestion[]> {
return []
},
}
}
}

get deviceConfig(): DeviceConfig {
return deviceConfig
}
Expand Down
18 changes: 16 additions & 2 deletions src/common/desktop/sse/SecretStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,25 @@ export class SafeStorageSecretStorage implements SecretStorage {
private async assertAvailable(): Promise<void> {
await this.electron.app.whenReady()
await this.fs.promises.mkdir(this.getSafeStoragePath(), { recursive: true })

const onLinux = process.platform === "linux"
const backend = onLinux ? this.electron.safeStorage.getSelectedStorageBackend() : null

if (!this.initialized && backend === "basic_text") {
// this will force isEncryptionAvailable to return true
this.electron.safeStorage.setUsePlainTextEncryption(true)

// note that `basic_text` uses a hardcoded key which is insecure
console.warn(
`Detected safeStorage backend is insecure: ${backend}. Consider choosing a different one via command line args, or set up an app password to protect local data`,
)
}

if (this.electron.safeStorage.isEncryptionAvailable()) {
if (!this.initialized && process.platform === "linux") {
if (!this.initialized && onLinux) {
// only linux has variable backends
this.initialized = true
console.log("using safeStorage with backend", this.electron.safeStorage.getSelectedStorageBackend())
console.log("using safeStorage with backend", backend)
}
return
}
Expand Down
10 changes: 9 additions & 1 deletion src/common/gui/base/buttons/RowButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,15 @@ export class RowButton implements Component<RowButtonAttrs> {
const color = attrs.selected ? theme.content_button_selected : theme.content_button
return m(BaseButton, {
label,
text: m(".plr-button.text-ellipsis", { style: { color } }, text),
text: m(
".plr-button.text-ellipsis",
{
style: { color },
// When the label doesn't match content, screen readers read both
ariaHidden: label !== text, // this prevents that
},
text,
),
role: attrs.role,
selected: attrs.selected,
icon:
Expand Down
Loading