WIP NIP-A0 voice messages
This commit is contained in:
@@ -33,6 +33,10 @@
|
||||
3A515C542DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A515C532DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift */; };
|
||||
3A515C552DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A515C532DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift */; };
|
||||
3A515C562DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A515C532DF5371D002D3B34 /* TrustedNetworkButtonTipViewStyle.swift */; };
|
||||
3A7379D42E5D5C4A00DF8B4E /* DSWaveformImageViews in Frameworks */ = {isa = PBXBuildFile; productRef = 3A7379D32E5D5C4A00DF8B4E /* DSWaveformImageViews */; };
|
||||
3A7379D72E5D5E1900DF8B4E /* DamusAudioPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A7379D62E5D5E1900DF8B4E /* DamusAudioPlayerView.swift */; };
|
||||
3A7379D82E5D5E1900DF8B4E /* DamusAudioPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A7379D62E5D5E1900DF8B4E /* DamusAudioPlayerView.swift */; };
|
||||
3A7379D92E5D5E1900DF8B4E /* DamusAudioPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A7379D62E5D5E1900DF8B4E /* DamusAudioPlayerView.swift */; };
|
||||
3A8CC6CC2A2CFEF900940F5F /* StringUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A8CC6CB2A2CFEF900940F5F /* StringUtil.swift */; };
|
||||
3A92C0FE2DE16E9800CEEBAC /* FaviconCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A92C0FD2DE16E9800CEEBAC /* FaviconCache.swift */; };
|
||||
3A92C0FF2DE16E9800CEEBAC /* FaviconCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A92C0FD2DE16E9800CEEBAC /* FaviconCache.swift */; };
|
||||
@@ -1923,6 +1927,7 @@
|
||||
3A66D927299472FA008B44F4 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
3A66D928299472FA008B44F4 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
3A66D929299472FA008B44F4 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ja; path = ja.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||
3A7379D62E5D5E1900DF8B4E /* DamusAudioPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusAudioPlayerView.swift; sourceTree = "<group>"; };
|
||||
3A821C3E29E819D500B4BCA7 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
3A821C3F29E819D500B4BCA7 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
3A821C4029E819D500B4BCA7 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = fr; path = fr.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||
@@ -2731,6 +2736,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3ACF94382DA9A52F00971A4E /* FaviconFinder in Frameworks */,
|
||||
3A7379D42E5D5C4A00DF8B4E /* DSWaveformImageViews in Frameworks */,
|
||||
4C06670428FC7EC500038D2A /* Kingfisher in Frameworks */,
|
||||
D7DB1FE42D5A9AC900CF06DA /* CryptoSwift in Frameworks */,
|
||||
3A0A30BB2C21397A00F8C9BC /* EmojiPicker in Frameworks */,
|
||||
@@ -2824,6 +2830,14 @@
|
||||
path = Tips;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3A7379D52E5D5DF000DF8B4E /* Audio */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3A7379D62E5D5E1900DF8B4E /* DamusAudioPlayerView.swift */,
|
||||
);
|
||||
path = Audio;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3AA24800297E3DAE0090C62D /* Reposts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -4392,6 +4406,7 @@
|
||||
children = (
|
||||
5C78A79D2E303D2600CF177D /* Models */,
|
||||
4CFF8F6129CC9A80008DB934 /* Images */,
|
||||
3A7379D52E5D5DF000DF8B4E /* Audio */,
|
||||
4C1A9A2829DDF53B00516EAC /* Video */,
|
||||
BA3759952ABCCF360018D73B /* Camera */,
|
||||
4C198DEA29F88C6B004C165C /* BlurHash */,
|
||||
@@ -5060,6 +5075,7 @@
|
||||
D7C48C0A2D12DE0C00A3BACF /* SwiftyCrop */,
|
||||
D7DB1FE32D5A9AC900CF06DA /* CryptoSwift */,
|
||||
3ACF94372DA9A52F00971A4E /* FaviconFinder */,
|
||||
3A7379D32E5D5C4A00DF8B4E /* DSWaveformImageViews */,
|
||||
);
|
||||
productName = damus;
|
||||
productReference = 4CE6DEE327F7A08100C66700 /* damus.app */;
|
||||
@@ -5271,6 +5287,7 @@
|
||||
D7C48C092D12DE0C00A3BACF /* XCRemoteSwiftPackageReference "SwiftyCrop" */,
|
||||
D7DB1FE22D5A9AC900CF06DA /* XCRemoteSwiftPackageReference "CryptoSwift" */,
|
||||
3ACF94362DA9A52F00971A4E /* XCRemoteSwiftPackageReference "FaviconFinder" */,
|
||||
3A7379D22E5D5C4A00DF8B4E /* XCRemoteSwiftPackageReference "DSWaveformImage" */,
|
||||
);
|
||||
productRefGroup = 4CE6DEE427F7A08100C66700 /* Products */;
|
||||
projectDirPath = "";
|
||||
@@ -5805,6 +5822,7 @@
|
||||
E0EE9DD42B8E5FEA00F3002D /* ImageProcessing.swift in Sources */,
|
||||
4CB883B0297705DD00DC99E7 /* NoteZapButton.swift in Sources */,
|
||||
D7DF58342DFCF18D00E9AD28 /* SendPaymentView.swift in Sources */,
|
||||
3A7379D72E5D5E1900DF8B4E /* DamusAudioPlayerView.swift in Sources */,
|
||||
4C363A922825FCF2006E126D /* ProfileUpdate.swift in Sources */,
|
||||
4C3BEFDA281DCA1400B3DE84 /* LikeCounter.swift in Sources */,
|
||||
4C32B9502A9AD44700DC3548 /* FlatBufferBuilder.swift in Sources */,
|
||||
@@ -6095,6 +6113,7 @@
|
||||
82D6FB092CD99F7900C925F4 /* SearchHeaderView.swift in Sources */,
|
||||
82D6FB0A2CD99F7900C925F4 /* DamusGradient.swift in Sources */,
|
||||
D7DB93052D66A44100DA1EE5 /* Undistractor.swift in Sources */,
|
||||
3A7379D92E5D5E1900DF8B4E /* DamusAudioPlayerView.swift in Sources */,
|
||||
82D6FB0C2CD99F7900C925F4 /* GoldSupportGradient.swift in Sources */,
|
||||
82D6FB0D2CD99F7900C925F4 /* PinkGradient.swift in Sources */,
|
||||
82D6FB0E2CD99F7900C925F4 /* GrayGradient.swift in Sources */,
|
||||
@@ -6780,6 +6799,7 @@
|
||||
D73E5F092C6A97F4007EB227 /* ProfilePicView.swift in Sources */,
|
||||
D73E5F0A2C6A97F4007EB227 /* ProfileView.swift in Sources */,
|
||||
D73E5F0B2C6A97F4007EB227 /* ProfileNameView.swift in Sources */,
|
||||
3A7379D82E5D5E1900DF8B4E /* DamusAudioPlayerView.swift in Sources */,
|
||||
D73E5F0C2C6A97F4007EB227 /* MaybeAnonPfpView.swift in Sources */,
|
||||
D73E5F0D2C6A97F4007EB227 /* EventProfileName.swift in Sources */,
|
||||
D73E5F0E2C6A97F4007EB227 /* FriendIcon.swift in Sources */,
|
||||
@@ -7922,6 +7942,14 @@
|
||||
minimumVersion = 0.2.0;
|
||||
};
|
||||
};
|
||||
3A7379D22E5D5C4A00DF8B4E /* XCRemoteSwiftPackageReference "DSWaveformImage" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/dmrschmidt/DSWaveformImage";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 14.2.2;
|
||||
};
|
||||
};
|
||||
3ACF94362DA9A52F00971A4E /* XCRemoteSwiftPackageReference "FaviconFinder" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/will-lumley/FaviconFinder.git";
|
||||
@@ -8010,6 +8038,11 @@
|
||||
package = 3A0A30B92C21397A00F8C9BC /* XCRemoteSwiftPackageReference "EmojiPicker" */;
|
||||
productName = EmojiPicker;
|
||||
};
|
||||
3A7379D32E5D5C4A00DF8B4E /* DSWaveformImageViews */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 3A7379D22E5D5C4A00DF8B4E /* XCRemoteSwiftPackageReference "DSWaveformImage" */;
|
||||
productName = DSWaveformImageViews;
|
||||
};
|
||||
3ACF94372DA9A52F00971A4E /* FaviconFinder */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 3ACF94362DA9A52F00971A4E /* XCRemoteSwiftPackageReference "FaviconFinder" */;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"originHash" : "1fc7e0b44329ba72cd285eeb022b5b92582cd01586b920d243cb0485c2e69dcc",
|
||||
"originHash" : "8d71e78d1d7bdc5a85a38932a14f84af755a9e34aeab19f9d540bd11a7b32fbc",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "codescanner",
|
||||
@@ -17,6 +17,15 @@
|
||||
"revision" : "e74bbbfbef939224b242ae7c342a90e60b88b5ce"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "dswaveformimage",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/dmrschmidt/DSWaveformImage",
|
||||
"state" : {
|
||||
"revision" : "4c56578ee10128ee2b2c04c9c5aa73812de722db",
|
||||
"version" : "14.2.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "emojikit",
|
||||
"kind" : "remoteSourceControl",
|
||||
|
||||
@@ -18,6 +18,7 @@ enum NostrKind: UInt32, Codable {
|
||||
case boost = 6
|
||||
case like = 7
|
||||
case chat = 42
|
||||
case voice_message = 1222
|
||||
case mute_list = 10000
|
||||
case relay_list = 10002
|
||||
case interest_list = 10015
|
||||
|
||||
@@ -62,7 +62,7 @@ class LoadableNostrEventViewModel: ObservableObject {
|
||||
guard let ev = await self.loadEvent(noteId: note_id) else { return .not_found }
|
||||
guard let known_kind = ev.known_kind else { return .unknown_or_unsupported_kind }
|
||||
switch known_kind {
|
||||
case .text, .highlight:
|
||||
case .text, .highlight, .voice_message:
|
||||
return .loaded(route: Route.Thread(thread: ThreadModel(event: ev, damus_state: damus_state)))
|
||||
case .dm:
|
||||
let dm_model = damus_state.dms.lookup_or_create(ev.pubkey)
|
||||
|
||||
@@ -319,6 +319,8 @@ func classify_url(_ url: URL) -> UrlType {
|
||||
return .media(.image(url))
|
||||
case "mp4", "mov", "m3u8":
|
||||
return .media(.video(url))
|
||||
case "m4a":
|
||||
return .media(.audio(url))
|
||||
default:
|
||||
return .link(url)
|
||||
}
|
||||
@@ -452,6 +454,8 @@ enum UrlType {
|
||||
return url
|
||||
case .video(let url):
|
||||
return url
|
||||
case .audio(let url):
|
||||
return url
|
||||
}
|
||||
case .link(let url):
|
||||
return url
|
||||
@@ -462,7 +466,7 @@ enum UrlType {
|
||||
switch self {
|
||||
case .media(let media_url):
|
||||
switch media_url {
|
||||
case .image:
|
||||
case .image, .audio:
|
||||
return nil
|
||||
case .video(let url):
|
||||
return url
|
||||
@@ -478,14 +482,28 @@ enum UrlType {
|
||||
switch media_url {
|
||||
case .image(let url):
|
||||
return url
|
||||
case .video:
|
||||
case .video, .audio:
|
||||
return nil
|
||||
}
|
||||
case .link:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var is_audio: URL? {
|
||||
switch self {
|
||||
case .media(let media_url):
|
||||
switch media_url {
|
||||
case .audio(let url):
|
||||
return url
|
||||
case .image, .video:
|
||||
return nil
|
||||
}
|
||||
case .link:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var is_link: URL? {
|
||||
switch self {
|
||||
case .media:
|
||||
@@ -508,13 +526,16 @@ enum UrlType {
|
||||
enum MediaUrl {
|
||||
case image(URL)
|
||||
case video(URL)
|
||||
|
||||
case audio(URL)
|
||||
|
||||
var url: URL {
|
||||
switch self {
|
||||
case .image(let url):
|
||||
return url
|
||||
case .video(let url):
|
||||
return url
|
||||
case .audio(let url):
|
||||
return url
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ struct NoteContentView: View {
|
||||
Divider()
|
||||
.frame(height: 1)
|
||||
switch artifacts.media[index] {
|
||||
case .image(let url), .video(let url):
|
||||
case .image(let url), .video(let url), .audio(let url):
|
||||
Text(abbreviateURL(url))
|
||||
.font(eventviewsize_to_font(size, font_size: damus_state.settings.font_size))
|
||||
.foregroundStyle(DamusColors.neutral6)
|
||||
@@ -477,7 +477,7 @@ struct BlurOverlayView: View {
|
||||
let damus_state = damus_state
|
||||
{
|
||||
switch artifacts.media[0] {
|
||||
case .image(let url), .video(let url):
|
||||
case .image(let url), .video(let url), .audio(let url):
|
||||
Text(abbreviateURL(url, maxLength: 30))
|
||||
.font(eventviewsize_to_font(size, font_size: damus_state.settings.font_size * 0.8))
|
||||
.foregroundStyle(.white)
|
||||
|
||||
@@ -75,7 +75,7 @@ class ProfileModel: ObservableObject, Equatable {
|
||||
}
|
||||
|
||||
func subscribe() {
|
||||
var text_filter = NostrFilter(kinds: [.text, .longform, .highlight])
|
||||
var text_filter = NostrFilter(kinds: [.text, .longform, .highlight, .voice_message])
|
||||
var profile_filter = NostrFilter(kinds: [.contacts, .metadata, .boost])
|
||||
var relay_list_filter = NostrFilter(kinds: [.relay_list], authors: [pubkey])
|
||||
|
||||
@@ -98,7 +98,7 @@ class ProfileModel: ObservableObject, Equatable {
|
||||
return
|
||||
}
|
||||
|
||||
let conversation_kinds: [NostrKind] = [.text, .longform, .highlight]
|
||||
let conversation_kinds: [NostrKind] = [.text, .longform, .highlight, .voice_message]
|
||||
let limit: UInt32 = 500
|
||||
let conversations_filter_them = NostrFilter(kinds: conversation_kinds, pubkeys: [damus.pubkey], limit: limit, authors: [pubkey])
|
||||
let conversations_filter_us = NostrFilter(kinds: conversation_kinds, pubkeys: [pubkey], limit: limit, authors: [damus.pubkey])
|
||||
@@ -122,7 +122,7 @@ class ProfileModel: ObservableObject, Equatable {
|
||||
}
|
||||
|
||||
private func add_event(_ ev: NostrEvent) {
|
||||
if ev.is_textlike || ev.known_kind == .boost {
|
||||
if ev.is_textlike || ev.known_kind == .boost || ev.known_kind == .voice_message {
|
||||
if self.events.insert(ev) {
|
||||
self.objectWillChange.send()
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ struct ProfileView: View {
|
||||
var filters = ContentFilters.defaults(damus_state: damus_state)
|
||||
filters.append(fstate.filter)
|
||||
switch fstate {
|
||||
case .posts, .posts_and_replies, .follow_list:
|
||||
case .posts, .posts_and_replies, .follow_list, .voice_messages:
|
||||
filters.append({ profile.pubkey == $0.pubkey })
|
||||
case .conversations:
|
||||
filters.append({ profile.conversation_events.contains($0.id) } )
|
||||
@@ -438,7 +438,8 @@ struct ProfileView: View {
|
||||
var tabs: [(String, FilterState)] {
|
||||
var tabs = [
|
||||
(NSLocalizedString("Notes", comment: "Label for filter for seeing only notes (instead of notes and replies)."), FilterState.posts),
|
||||
(NSLocalizedString("Notes & Replies", comment: "Label for filter for seeing notes and replies (instead of only notes)."), FilterState.posts_and_replies)
|
||||
(NSLocalizedString("Notes & Replies", comment: "Label for filter for seeing notes and replies (instead of only notes)."), FilterState.posts_and_replies),
|
||||
(NSLocalizedString("Voice", comment: "Label for filter for seeing voice messages."), FilterState.voice_messages)
|
||||
]
|
||||
if profile.pubkey != damus_state.pubkey && !profile.conversation_events.isEmpty {
|
||||
tabs.append((NSLocalizedString("Conversations", comment: "Label for filter for seeing notes and replies that involve conversations between the signed in user and the current profile."), FilterState.conversations))
|
||||
@@ -469,6 +470,9 @@ struct ProfileView: View {
|
||||
if filter_state == FilterState.posts_and_replies {
|
||||
InnerTimelineView(events: profile.events, damus: damus_state, filter: content_filter(FilterState.posts_and_replies))
|
||||
}
|
||||
if filter_state == FilterState.voice_messages {
|
||||
InnerTimelineView(events: profile.events, damus: damus_state, filter: content_filter(FilterState.voice_messages))
|
||||
}
|
||||
if filter_state == FilterState.conversations && !profile.conversation_events.isEmpty {
|
||||
InnerTimelineView(events: profile.events, damus: damus_state, filter: content_filter(FilterState.conversations))
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ enum FilterState : Int {
|
||||
case posts_and_replies = 1
|
||||
case conversations = 2
|
||||
case follow_list = 3
|
||||
case voice_messages = 4
|
||||
|
||||
func filter(ev: NostrEvent) -> Bool {
|
||||
switch self {
|
||||
@@ -25,6 +26,8 @@ enum FilterState : Int {
|
||||
return true
|
||||
case .follow_list:
|
||||
return ev.known_kind == .follow_list
|
||||
case .voice_messages:
|
||||
return ev.known_kind == .voice_message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,6 +192,8 @@ class HomeModel: ContactsDelegate {
|
||||
switch kind {
|
||||
case .chat, .longform, .text, .highlight:
|
||||
handle_text_event(sub_id: sub_id, ev)
|
||||
case .voice_message:
|
||||
handle_voice_message_event(sub_id: sub_id, ev)
|
||||
case .contacts:
|
||||
handle_contact_event(sub_id: sub_id, relay_id: relay_id, ev: ev)
|
||||
case .metadata:
|
||||
@@ -776,7 +778,28 @@ class HomeModel: ContactsDelegate {
|
||||
handle_notification(ev: ev)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func handle_voice_message_event(sub_id: String, _ ev: NostrEvent) {
|
||||
guard should_show_event(state: damus_state, ev: ev) else {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: will we need to process this in other places like zap request contents, etc?
|
||||
process_image_metadatas(cache: damus_state.events, ev: ev)
|
||||
damus_state.replies.count_replies(ev, keypair: self.damus_state.keypair)
|
||||
damus_state.events.insert(ev)
|
||||
|
||||
if let quoted_event = ev.referenced_quote_ids.first {
|
||||
handle_quote_repost_event(ev, target: quoted_event.note_id)
|
||||
}
|
||||
|
||||
if sub_id == home_subid {
|
||||
insert_home_event(ev)
|
||||
} else if sub_id == notifications_subid {
|
||||
handle_notification(ev: ev)
|
||||
}
|
||||
}
|
||||
|
||||
func got_new_dm(notifs: NewEventsBits, ev: NostrEvent) {
|
||||
notification_status.new_events = notifs
|
||||
|
||||
|
||||
44
damus/Shared/Media/Audio/DamusAudioPlayerView.swift
Normal file
44
damus/Shared/Media/Audio/DamusAudioPlayerView.swift
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// DamusAudioPlayerView.swift
|
||||
// damus
|
||||
//
|
||||
// Created by Terry Yiu on 8/25/25.
|
||||
//
|
||||
|
||||
import DSWaveformImageViews
|
||||
import SwiftUI
|
||||
|
||||
struct DamusAudioPlayerView: View {
|
||||
let remoteURL: URL
|
||||
@State var localURL: URL
|
||||
|
||||
var body: some View {
|
||||
GeometryReader { geometry in
|
||||
WaveformView(audioURL: localURL) { shape in
|
||||
shape.fill(.white)
|
||||
shape.fill(.red).mask(alignment: .leading) {
|
||||
Rectangle().frame(width: geometry.size.width * progress)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text("Hello, World!")
|
||||
.task {
|
||||
URLSession.shared.downloadTask(with: remoteURL) { downloadedURL, urlResponse, error in
|
||||
guard let downloadedURL = downloadedURL else { return }
|
||||
|
||||
let cachesFolderURL = try? FileManager.default.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
|
||||
let audioFileURL = cachesFolderURL!.appendingPathComponent("yourLocalAudioFile.m4a")
|
||||
try? FileManager.default.copyItem(at: downloadedURL, to: audioFileURL)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.localURL = audioFileURL
|
||||
// self.WaveformView.waveformAudioURL = audioFileURL
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
DamusAudioPlayerView()
|
||||
}
|
||||
@@ -57,7 +57,9 @@ struct ImageContainerView: View {
|
||||
switch url {
|
||||
case .image(let url):
|
||||
Img(url: url)
|
||||
case .video(let url):
|
||||
case .audio(let url):
|
||||
DamusAudioPlayerView()
|
||||
case .video(let url):
|
||||
DamusVideoPlayerView(url: url, coordinator: video_coordinator, style: .no_controls(on_tap: nil))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ class CarouselModel: ObservableObject {
|
||||
private func observe_video_sizes() {
|
||||
for media_url in urls {
|
||||
switch media_url {
|
||||
case .video(let url):
|
||||
case .video(let url), .audio(let url):
|
||||
let video_player = damus_state.video.get_player(for: url)
|
||||
if let video_size = video_player.video_size {
|
||||
self.media_size_information[url] = video_size // Set the initial size if available
|
||||
@@ -302,6 +302,7 @@ class CarouselModel: ObservableObject {
|
||||
struct ImageCarousel<Content: View>: View {
|
||||
/// The event id of the note that this carousel is displaying
|
||||
let evid: NoteId
|
||||
let event: NostrEvent
|
||||
/// The model that holds information and state of this carousel
|
||||
/// This is observed to update the view when the model changes
|
||||
@ObservedObject var model: CarouselModel
|
||||
@@ -354,6 +355,8 @@ struct ImageCarousel<Content: View>: View {
|
||||
.onTapGesture {
|
||||
present(full_screen_item: .full_screen_carousel(urls: model.urls, selectedIndex: $model.selectedIndex))
|
||||
}
|
||||
case .audio(let url):
|
||||
DamusAudioPlayerView()
|
||||
case .video(let url):
|
||||
let video_model = model.damus_state.video.get_player(for: url)
|
||||
DamusVideoPlayerView(
|
||||
|
||||
Reference in New Issue
Block a user