Skip to content

Commit

Permalink
[Calendar] [ios] Adds tutacalshare as Tuta Calendar sharing scheme
Browse files Browse the repository at this point in the history
This commit adds a different scheme to share files with Tuta Calendar on
ios. This scheme prevents ios devices from opening Tuta Mail when
sharing a file.
  • Loading branch information
mup authored and tutao-mac committed Aug 19, 2024
1 parent 3641db5 commit 388085b
Show file tree
Hide file tree
Showing 17 changed files with 50 additions and 26 deletions.
9 changes: 8 additions & 1 deletion app-ios/TutanotaShareExtension/ShareViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ import WebKit

private func openMainAppWithOpenUrl(_ infoLocation: String) {
var components = URLComponents()
components.scheme = TUTANOTA_SHARE_SCHEME
components.scheme = self.selectAppSchema()
components.host = infoLocation
self.extensionContext?
.completeRequest(returningItems: nil) { (_: Bool) in
Expand All @@ -86,6 +86,13 @@ import WebKit
}
}

private func selectAppSchema() -> String {
let bundleId = Bundle.main.bundleIdentifier
if let isCalendarApp = bundleId?.contains("calendar") { return CALENDAR_SHARE_SCHEME }

return TUTANOTA_SHARE_SCHEME
}

@objc func openURL(_ url: URL) -> Bool {
var responder: UIResponder? = self
while responder != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.de.tutao.calendar</string>
<string>group.de.tutao.tutanota</string>
</array>
</dict>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.de.tutao.tutanota.debug</string>
<string>group.de.tutao.calendar.debug</string>
</array>
</dict>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.de.tutao.calendar.test</string>
<string>group.de.tutao.tutanota.test</string>
</array>
</dict>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.de.tutao.calendar.debug</string>
<string>group.de.tutao.tutanota.debug</string>
</array>
</dict>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.de.tutao.calendar.test</string>
<string>group.de.tutao.tutanota.test</string>
</array>
</dict>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import RegexBuilder
import UIKit

public let TUTANOTA_SHARE_SCHEME = "tutashare"
public let CALENDAR_SHARE_SCHEME = "tutacalshare"

/// this gets shared to the main app and contains all the info
/// to create a new mail & the cleanup
Expand Down Expand Up @@ -151,7 +152,6 @@ public func writeSharingInfo(info: SharingInfo, infoLocation: String) throws {
public func readSharingInfo(infoLocation: String) -> SharingInfo? {
guard let defaults = try? getSharedDefaults() else { return nil }
defer { defaults.removeObject(forKey: infoLocation) }

guard let data: Data = defaults.value(forKey: infoLocation) as! Data? else {
TUTSLog("there are no sharingInfos to be found at \(infoLocation)")
return nil
Expand Down
4 changes: 2 additions & 2 deletions app-ios/calendar/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
<string>de.tutao.calendar</string>
<key>CFBundleURLSchemes</key>
<array>
<string>tutashare</string>
<string>calendar</string>
<string>tutacalshare</string>
<string>tutanota</string>
</array>
</dict>
</array>
Expand Down
4 changes: 2 additions & 2 deletions app-ios/calendar/Sources/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ import UIKit

/// handles tutanota deep links:
/// tutanota:// -> ?
/// tutashare:// -> share requests from the sharing extension
/// tutacalshare:// -> share requests from the sharing extension
func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
switch url.scheme {
case TUTANOTA_SHARE_SCHEME: Task { try! await self.viewController.handleShare(url) }
case CALENDAR_SHARE_SCHEME: Task { try! await self.viewController.handleShare(url) }
case nil: TUTSLog("missing scheme!")
default: TUTSLog("unknown scheme? \(url.scheme!)")
}
Expand Down
2 changes: 1 addition & 1 deletion src/calendar-app/calendar/view/CalendarView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { CalendarMonthView } from "./CalendarMonthView"
import { DateTime } from "luxon"
import { NotFoundError } from "../../../common/api/common/error/RestError"
import { CalendarAgendaView, CalendarAgendaViewAttrs } from "./CalendarAgendaView"
import { createDefaultAlarmInfo } from "../../../common/api/entities/sys/TypeRefs.js"
import { createDefaultAlarmInfo, GroupInfo } from "../../../common/api/entities/sys/TypeRefs.js"
import { showEditCalendarDialog } from "../gui/EditCalendarDialog.js"
import { styles } from "../../../common/gui/styles"
import { MultiDayCalendarView } from "./MultiDayCalendarView"
Expand Down
5 changes: 3 additions & 2 deletions src/calendar-app/calendarLocator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ class CalendarLocator {
const domainConfig = isBrowser()
? calendarLocator.domainConfigProvider().getDomainConfigForHostname(location.hostname, location.protocol, location.port)
: // in this case, we know that we have a staticUrl set that we need to use
calendarLocator.domainConfigProvider().getCurrentDomainConfig()
calendarLocator.domainConfigProvider().getCurrentDomainConfig()

return new LoginViewModel(
calendarLocator.logins,
Expand Down Expand Up @@ -592,6 +592,7 @@ class CalendarLocator {
async () => this.fileApp,
async () => this.pushService,
this.handleFileImport.bind(this),
AppType.Calendar,
),
cryptoFacade,
calendarFacade,
Expand Down Expand Up @@ -727,7 +728,7 @@ class CalendarLocator {

private async handleFileImport(filesUris: ReadonlyArray<string>) {
const files = await this.fileApp.getFilesMetaData(filesUris)
const areAllICSFiles = files.every(file => file.mimeType === CALENDAR_MIME_TYPE)
const areAllICSFiles = files.every((file) => file.mimeType === CALENDAR_MIME_TYPE)
if (areAllICSFiles) {
const calendarModel = await this.calendarModel()
const groupSettings = this.logins.getUserController().userSettingsGroupRoot.groupSettings
Expand Down
1 change: 1 addition & 0 deletions src/common/misc/TranslationKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1735,3 +1735,4 @@ export type TranslationKeyType =
| "importEvents_label"
| "calendarImportSelection_label"
| "icsInSharingFiles_msg"
| "invalidCalendarFile_msg"
27 changes: 18 additions & 9 deletions src/common/native/main/WebCommonNativeFacade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { UsageTestController } from "@tutao/tutanota-usagetests"
import { NativeFileApp } from "../common/FileApp.js"
import { NativePushServiceApp } from "./NativePushServiceApp.js"
import { locator } from "../../api/main/CommonLocator.js"
import { AppType } from "../../misc/ClientConstants.js"

export class WebCommonNativeFacade implements CommonNativeFacade {
constructor(
Expand All @@ -22,8 +23,8 @@ export class WebCommonNativeFacade implements CommonNativeFacade {
private readonly fileApp: lazyAsync<NativeFileApp>,
private readonly pushService: lazyAsync<NativePushServiceApp>,
private readonly fileImportHandler: (filesUris: ReadonlyArray<string>) => unknown,
) {
}
private readonly appType: AppType,
) {}

/**
* create a mail editor as requested from the native side, ie because a
Expand Down Expand Up @@ -60,6 +61,14 @@ export class WebCommonNativeFacade implements CommonNativeFacade {
const allFilesAreVCards = files.length > 0 && files.every((file) => getAttachmentType(file.mimeType) === AttachmentType.CONTACT)
const allFilesAreICS = files.length > 0 && files.every((file) => getAttachmentType(file.mimeType) === AttachmentType.CALENDAR)

if (this.appType === AppType.Calendar) {
if (!allFilesAreICS) {
return Dialog.message("invalidCalendarFile_msg")
}

return this.handleFileImport(filesUris)
}

let willImport = false
if (allFilesAreVCards) {
willImport = await Dialog.choice("vcardInSharingFiles_msg", [
Expand All @@ -85,13 +94,13 @@ export class WebCommonNativeFacade implements CommonNativeFacade {
const address = (addresses && addresses[0]) || ""
const recipients = address
? {
to: [
{
name: "",
address: address,
},
],
}
to: [
{
name: "",
address: address,
},
],
}
: {}
editor = await newMailEditorFromTemplate(
mailboxDetails,
Expand Down
11 changes: 6 additions & 5 deletions src/mail-app/mailLocator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,8 @@ class MailLocator {
readonly mailOpenedListener: MailOpenedListener = {
onEmailOpened: isDesktop()
? (mail) => {
this.desktopSystemFacade.sendSocketMessage(getDisplayedSender(mail).address)
}
this.desktopSystemFacade.sendSocketMessage(getDisplayedSender(mail).address)
}
: noOp,
}

Expand Down Expand Up @@ -565,7 +565,7 @@ class MailLocator {
const domainConfig = isBrowser()
? mailLocator.domainConfigProvider().getDomainConfigForHostname(location.hostname, location.protocol, location.port)
: // in this case, we know that we have a staticUrl set that we need to use
mailLocator.domainConfigProvider().getCurrentDomainConfig()
mailLocator.domainConfigProvider().getCurrentDomainConfig()

return new LoginViewModel(
mailLocator.logins,
Expand Down Expand Up @@ -708,6 +708,7 @@ class MailLocator {
async () => this.fileApp,
async () => this.pushService,
this.handleFileImport.bind(this),
AppType.Integrated,
),
cryptoFacade,
calendarFacade,
Expand Down Expand Up @@ -866,8 +867,8 @@ class MailLocator {

private async handleFileImport(filesUris: ReadonlyArray<string>) {
const files = await this.fileApp.getFilesMetaData(filesUris)
const areAllFilesVCard = files.every(file => file.mimeType === VCARD_MIME_TYPES.X_VCARD || file.mimeType === VCARD_MIME_TYPES.VCARD)
const areAllFilesICS = files.every(file => file.mimeType === CALENDAR_MIME_TYPE)
const areAllFilesVCard = files.every((file) => file.mimeType === VCARD_MIME_TYPES.X_VCARD || file.mimeType === VCARD_MIME_TYPES.VCARD)
const areAllFilesICS = files.every((file) => file.mimeType === CALENDAR_MIME_TYPE)

if (areAllFilesVCard) {
const importer = await this.contactImporter()
Expand Down
2 changes: 1 addition & 1 deletion src/mail-app/translations/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1752,8 +1752,8 @@ export default {
"yourMessage_label": "Deine Nachricht",
"you_label": "Du",
"importEvents_label": "Terminen wird importiert",
"calendarDefaultReminder_label": "Standard-Terminerinnerung",
"calendarImportSelection_label": "Wählen Sie einen Kalender aus, in den Sie Ihre Ereignisse importieren möchten.",
"icsInSharingFiles_msg": "Eine oder mehrere Kalenderdateien wurden erkannt. Möchten Sie sie importieren oder anhängen?",
"invalidCalendarFile_msg": "Eine oder mehrere Dateien sind keine gültigen Kalenderdateien."
}
}
2 changes: 1 addition & 1 deletion src/mail-app/translations/de_sie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1752,8 +1752,8 @@ export default {
"yourMessage_label": "Ihre Nachricht",
"you_label": "Sie",
"importEvents_label": "Terminen wird importiert",
"calendarDefaultReminder_label": "Standard-Terminerinnerung",
"calendarImportSelection_label": "Wählen Sie einen Kalender aus, in den Sie Ihre Ereignisse importieren möchten.",
"icsInSharingFiles_msg": "Eine oder mehrere Kalenderdateien wurden erkannt. Möchten Sie sie importieren oder anhängen?",
"invalidCalendarFile_msg": "Eine oder mehrere Dateien sind keine gültigen Kalenderdateien."
}
}
2 changes: 1 addition & 1 deletion src/mail-app/translations/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1748,8 +1748,8 @@ export default {
"yourMessage_label": "Your message",
"you_label": "You",
"importEvents_label": "Import Events",
"calendarDefaultReminder_label": "Default reminder before event",
"calendarImportSelection_label": "Select a calendar to import your events into",
"icsInSharingFiles_msg": "One or more calendar files were detected. Would you like to import or attach them?",
"invalidCalendarFile_msg": "One or more files aren't valid calendar files."
}
}

0 comments on commit 388085b

Please sign in to comment.