Add iOS Share Extension

This commit is contained in:
Leon Böttger committed 2025-08-17 19:03:47 +02:00
1 parent 13ce7522a7
commit 406247d968
13 files changed
+602 -147

No files matched your search

+95 -64
View File
@@ -10,12 +10,11 @@ import LUI
struct ContentView: View {
@StateObject var sendModel = SendModel()
@StateObject var receiveModel = ReceiveModel()
var attachments: AttachmentDetails? = nil
var body: some View {
AppRootView(isPlus: .constant(true), phoneView: {
DeviceListView(sendModel: sendModel, receiveModel: receiveModel)
DeviceListView(attachments: attachments)
}, settingsView: {
EmptyView()
})
@@ -24,8 +23,13 @@ struct ContentView: View {
struct DeviceListView: View {
@ObservedObject var sendModel: SendModel
@ObservedObject var receiveModel: ReceiveModel
var attachments: AttachmentDetails? = nil
@StateObject var sendModel = SendModel()
#if !EXTENSION
@StateObject var receiveModel = ReceiveModel()
#endif
var body: some View {
@@ -67,53 +71,25 @@ struct DeviceListView: View {
let isSelected = sendModel.selectedDevice == device
SendPickerButton {
HStack(spacing: 12) {
let name = device.name ?? "Android"
ZStack {
Circle()
.fill(
LinearGradient(
colors: [Color(red: 0.623, green: 0.659, blue: 0.855),
Color(red: 0.474, green: 0.525, blue: 0.796)],
startPoint: .top,
endPoint: .bottom
)
)
.frame(width: 40, height: 40)
Image(systemName: device.icon)
.foregroundColor(.white)
.fontWeight(.bold)
ZStack {
if let attachments = attachments {
LUIButton {
sendModel.urls = attachments.urls
sendModel.textToSend = attachments.textToSend
sendModel.selectDevice(device: device)
} label: {
DeviceButton(device: device, isSelected: isSelected, progress: sendModel.progressState, progressValue: sendModel.progressValue)
}
VStack(alignment: .leading, spacing: 5) {
Text(name)
.fontWeight(.medium)
.foregroundColor(Color.primary)
Text(isSelected ? sendModel.progressState ?? "..." : "Available".localized())
.font(.system(size: 12))
.foregroundColor(Color.primary.opacity(0.6))
}
Spacer()
if isSelected, let progress = sendModel.progressValue {
PieProgressView(progress: progress, size: 20)
}
else {
Image(systemName: "chevron.right")
.foregroundColor(Color.primary.opacity(0.6))
}
else {
SendPickerButton {
DeviceButton(device: device, isSelected: isSelected, progress: sendModel.progressState, progressValue: sendModel.progressValue)
} onResult: { urls, text in
sendModel.urls = urls ?? []
sendModel.textToSend = text
sendModel.selectDevice(device: device)
}
}
.padding(.vertical, 13)
} onResult: { urls, text in
sendModel.urls = urls ?? []
sendModel.textToSend = text
sendModel.selectDevice(device: device)
}
.animation(.easeInOut, value: sendModel.progressValue)
.animation(.easeInOut, value: isSelected)
@@ -135,21 +111,76 @@ struct DeviceListView: View {
}
}
extension DeviceListView {
static var preview: DeviceListView {
let model = SendModel()
model.foundDevices = [
RemoteDeviceInfo(name: "MacBook Pro", type: .computer, id: "macbook-pro-id"),
RemoteDeviceInfo(name: "iPhone 14", type: .phone, id: "iphone-14-id"),
RemoteDeviceInfo(name: "Samsung Galaxy S21", type: .phone, id: "samsung-galaxy-s21-id")
]
return DeviceListView(sendModel: model, receiveModel: ReceiveModel())
struct DeviceButton: View {
let device: RemoteDeviceInfo
let isSelected: Bool
let progress: String?
let progressValue: Double?
var body: some View {
HStack(spacing: 12) {
let name = device.name ?? "Android"
ZStack {
Circle()
.fill(
LinearGradient(
colors: [Color(red: 0.623, green: 0.659, blue: 0.855),
Color(red: 0.474, green: 0.525, blue: 0.796)],
startPoint: .top,
endPoint: .bottom
)
)
.frame(width: 40, height: 40)
Image(systemName: device.icon)
.foregroundColor(.white)
.fontWeight(.bold)
}
VStack(alignment: .leading, spacing: 5) {
Text(name)
.fontWeight(.medium)
.foregroundColor(Color.primary)
Text(isSelected ? progress ?? "..." : "Available".localized())
.font(.system(size: 12))
.foregroundColor(Color.primary.opacity(0.6))
}
Spacer()
if isSelected, let progress = progressValue {
PieProgressView(progress: progress, size: 20)
}
else {
Image(systemName: "chevron.right")
.foregroundColor(Color.primary.opacity(0.6))
}
}
.padding(.vertical, 13)
}
}
#Preview {
NavigationView {
DeviceListView.preview
}
}
//extension DeviceListView {
// static var preview: DeviceListView {
// let model = SendModel()
// model.foundDevices = [
// RemoteDeviceInfo(name: "MacBook Pro", type: .computer, id: "macbook-pro-id"),
// RemoteDeviceInfo(name: "iPhone 14", type: .phone, id: "iphone-14-id"),
// RemoteDeviceInfo(name: "Samsung Galaxy S21", type: .phone, id: "samsung-galaxy-s21-id")
// ]
//
// return DeviceListView(sendModel: model, receiveModel: ReceiveModel())
// }
//}
//
//#Preview {
// NavigationView {
// DeviceListView.preview
// }
//}