Files
damus/damus/Views/AttachMediaUtility.swift
Daniel D’Aquino 88f938d11c Bring local notification logic into the push notification target
This commit brings key local notification logic into the notification
extension target to allow the extension to reuse much of the
functionality surrounding the processing and formatting of
notifications. More specifically, the functions
`process_local_notification` and `create_local_notification` were
brought into the extension target.

This will enable us to reuse much of the pre-existing notification logic
(and avoid having to reimplement all of that)

However, those functions had high dependencies on other parts of the
code, so significant refactorings were needed to make this happen:

- `create_local_notification` and `process_local_notification` had its
  function signatures changed to avoid the need to `DamusState` (which
  pulls too many other dependecies)

- Other necessary dependencies, such as `Profiles`, `UserSettingsStore`
  had to be pulled into the extension target. Subsequently,
  sub-dependencies of those items had to be pulled in as well

- In several cases, files were split to avoid pulling too many
  dependencies (e.g. Some Model files depended on some functions in View
  files, so in those cases I moved those functions into their own
  separate file to avoid pulling in view logic into the extension
  target)

- Notification processing logic was changed a bit to remove dependency
  on `EventCache` in favor of using ndb directly (As instructed in a
  TODO comment in EventCache, and because EventCache has too many other
  dependencies)

tldr: A LOT of things were moved around, a bit of logic was changed
around local notifications to avoid using `EventCache`, but otherwise
this commit is meant to be a no-op without any new features or
user-facing functional changes.

Testing
-------

Device: iPhone 15 Pro
iOS: 17.0.1
Damus: This commit
Coverage:

1. Ran unit tests to check for regressions (none detected)

2. Launched the app and navigated around and did some interactions to
   perform a quick functional smoke test (no regressions found)

3. Sent a few push notifications to check they still work as expected (PASS)

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Signed-off-by: William Casarin <jb55@jb55.com>
2024-01-10 11:06:30 -08:00

95 lines
3.0 KiB
Swift

//
// AttachMediaUtility.swift
// damus
//
// Created by Swift on 2/17/23.
//
import SwiftUI
import UIKit
import CoreGraphics
import UniformTypeIdentifiers
enum ImageUploadResult {
case success(String)
case failed(Error?)
}
fileprivate func create_upload_body(mediaData: Data, boundary: String, mediaUploader: MediaUploader, mediaToUpload: MediaUpload) -> Data {
let body = NSMutableData();
let contentType = mediaToUpload.is_image ? "image/jpg" : "video/mp4"
body.appendString(string: "Content-Type: multipart/form-data; boundary=\(boundary)\r\n\r\n")
body.appendString(string: "--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\(mediaUploader.nameParam); filename=\(mediaToUpload.genericFileName)\r\n")
body.appendString(string: "Content-Type: \(contentType)\r\n\r\n")
body.append(mediaData as Data)
body.appendString(string: "\r\n")
body.appendString(string: "--\(boundary)--\r\n")
return body as Data
}
func create_upload_request(mediaToUpload: MediaUpload, mediaUploader: MediaUploader, progress: URLSessionTaskDelegate, keypair: Keypair? = nil) async -> ImageUploadResult {
var mediaData: Data?
guard let url = URL(string: mediaUploader.postAPI) else {
return .failed(nil)
}
var request = URLRequest(url: url)
request.httpMethod = "POST";
let boundary = "Boundary-\(UUID().description)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
// If uploading to a media host that support NIP-98 authorization, add the header
if mediaUploader == .nostrBuild,
let keypair,
let method = request.httpMethod,
let signature = create_nip98_signature(keypair: keypair, method: method, url: url) {
request.setValue(signature, forHTTPHeaderField: "Authorization")
}
switch mediaToUpload {
case .image(let url):
do {
mediaData = try Data(contentsOf: url)
} catch {
return .failed(error)
}
case .video(let url):
do {
mediaData = try Data(contentsOf: url)
} catch {
return .failed(error)
}
}
guard let mediaData else {
return .failed(nil)
}
request.httpBody = create_upload_body(mediaData: mediaData, boundary: boundary, mediaUploader: mediaUploader, mediaToUpload: mediaToUpload)
do {
let (data, _) = try await URLSession.shared.data(for: request, delegate: progress)
guard let url = mediaUploader.getMediaURL(from: data) else {
print("Upload failed getting media url")
return .failed(nil)
}
return .success(url)
} catch {
return .failed(error)
}
}
extension NSMutableData {
func appendString(string: String) {
guard let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true) else {
return
}
append(data)
}
}