Repository navigation
feat/add image viewer #162
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
Merged
Merged
Changes from 7 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
532a681
0.2.6
matheusfillipe 6291202
Merge branch 'main' of https://github.com/ObsidianIRC/ObsidianIRC
matheusfillipe 8fb7414
Add image view modal
matheusfillipe 6e63e43
Add share dialog in mobile
matheusfillipe f3ad23b
fix biome
matheusfillipe c7b70ec
remove download button in browser
matheusfillipe e9c1321
Add a filmstrip in the image viewer
matheusfillipe c2cef59
horizontal scroll in filmstrip
matheusfillipe 1434728
Small fixes
matheusfillipe cd9eeef
Add comments section
matheusfillipe e109794
Add reactions, avatars, image previews in the comment section
matheusfillipe 780b838
add image thumbnail to replies
matheusfillipe 79f0833
enforce media trust settings in reply thumbnails and filmstrip
matheusfillipe 35ae54f
make it resizable
matheusfillipe 880d564
Some review feedback
matheusfillipe 26d369c
mobile fixes
matheusfillipe ceaa702
Small fixes with mobile keyboard
matheusfillipe 4f5f16f
feat/add more media providers and previews (#163)
matheusfillipe 90bf0ef
Merge remote-tracking branch 'origin/main' into feat/add-image-preview
matheusfillipe c9d2f90
biome
matheusfillipe File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| .DS_Store | ||
| /.build | ||
| /Packages | ||
| /*.xcodeproj | ||
| xcuserdata/ | ||
| DerivedData/ | ||
| .swiftpm/config/registries.json | ||
| .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata | ||
| .netrc | ||
| Package.resolved |
40 changes: 40 additions & 0 deletions
40
src-tauri/plugins/share-sheet/.tauri/tauri-api/Package.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| // swift-tools-version:5.3 | ||
| // Copyright 2019-2024 Tauri Programme within The Commons Conservancy | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| import PackageDescription | ||
|
|
||
| let package = Package( | ||
| name: "Tauri", | ||
| platforms: [ | ||
| .macOS(.v10_13), | ||
| .iOS(.v11), | ||
| ], | ||
| products: [ | ||
| // Products define the executables and libraries a package produces, and make them visible to other packages. | ||
| .library( | ||
| name: "Tauri", | ||
| type: .static, | ||
| targets: ["Tauri"]) | ||
| ], | ||
| dependencies: [ | ||
| // Dependencies declare other packages that this package depends on. | ||
| .package(name: "SwiftRs", url: "https://github.com/Brendonovich/swift-rs", from: "1.0.0") | ||
| ], | ||
| targets: [ | ||
| // Targets are the basic building blocks of a package. A target can define a module or a test suite. | ||
| // Targets can depend on other targets in this package, and on products in packages this package depends on. | ||
| .target( | ||
| name: "Tauri", | ||
| dependencies: [ | ||
| .byName(name: "SwiftRs") | ||
| ], | ||
| path: "Sources" | ||
| ), | ||
| .testTarget( | ||
| name: "TauriTests", | ||
| dependencies: ["Tauri"] | ||
| ), | ||
| ] | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # Tauri | ||
|
|
||
| Tauri iOS API. |
65 changes: 65 additions & 0 deletions
65
src-tauri/plugins/share-sheet/.tauri/tauri-api/Sources/Tauri/Channel.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| // Copyright 2019-2024 Tauri Programme within The Commons Conservancy | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| import Foundation | ||
|
|
||
| let CHANNEL_PREFIX = "__CHANNEL__:" | ||
| let channelDataKey = CodingUserInfoKey(rawValue: "sendChannelData")! | ||
|
|
||
| public class Channel: Decodable { | ||
| public let id: UInt64 | ||
| let handler: (UInt64, String) -> Void | ||
|
|
||
| public required init(from decoder: Decoder) throws { | ||
| let container = try decoder.singleValueContainer() | ||
| let channelDef = try container.decode(String.self) | ||
|
|
||
| let components = channelDef.components(separatedBy: CHANNEL_PREFIX) | ||
| if components.count < 2 { | ||
| throw DecodingError.dataCorruptedError( | ||
| in: container, | ||
| debugDescription: "Invalid channel definition from \(channelDef)" | ||
| ) | ||
|
|
||
| } | ||
| guard let channelId = UInt64(components[1]) else { | ||
| throw DecodingError.dataCorruptedError( | ||
| in: container, | ||
| debugDescription: "Invalid channel ID from \(channelDef)" | ||
| ) | ||
| } | ||
|
|
||
| guard let handler = decoder.userInfo[channelDataKey] as? (UInt64, String) -> Void else { | ||
| throw DecodingError.dataCorruptedError( | ||
| in: container, | ||
| debugDescription: "missing userInfo for Channel handler. This is a Tauri issue" | ||
| ) | ||
| } | ||
|
|
||
| self.id = channelId | ||
| self.handler = handler | ||
| } | ||
|
|
||
| func serialize(_ data: JsonValue) -> String { | ||
| do { | ||
| return try data.jsonRepresentation() ?? "\"Failed to serialize payload\"" | ||
| } catch { | ||
| return "\"\(error)\"" | ||
| } | ||
| } | ||
|
|
||
| public func send(_ data: JsonObject) { | ||
| send(.dictionary(data)) | ||
| } | ||
|
|
||
| public func send(_ data: JsonValue) { | ||
| handler(id, serialize(data)) | ||
| } | ||
|
|
||
| public func send<T: Encodable>(_ data: T) throws { | ||
| let json = try JSONEncoder().encode(data) | ||
| handler(id, String(decoding: json, as: UTF8.self)) | ||
| } | ||
|
|
||
| } |
118 changes: 118 additions & 0 deletions
118
src-tauri/plugins/share-sheet/.tauri/tauri-api/Sources/Tauri/Invoke.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| // Copyright 2019-2024 Tauri Programme within The Commons Conservancy | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| import Foundation | ||
| import UIKit | ||
|
|
||
| @objc public class Invoke: NSObject { | ||
| public let command: String | ||
| let callback: UInt64 | ||
| let error: UInt64 | ||
| let data: String | ||
| let sendResponse: (UInt64, String?) -> Void | ||
| let sendChannelData: (UInt64, String) -> Void | ||
|
|
||
| public init( | ||
| command: String, callback: UInt64, error: UInt64, | ||
| sendResponse: @escaping (UInt64, String?) -> Void, | ||
| sendChannelData: @escaping (UInt64, String) -> Void, data: String | ||
| ) { | ||
| self.command = command | ||
| self.callback = callback | ||
| self.error = error | ||
| self.data = data | ||
| self.sendResponse = sendResponse | ||
| self.sendChannelData = sendChannelData | ||
| } | ||
|
|
||
| public func getRawArgs() -> String { | ||
| return self.data | ||
| } | ||
|
|
||
| public func getArgs() throws -> JSObject { | ||
| let jsonData = self.data.data(using: .utf8)! | ||
| let data = try JSONSerialization.jsonObject(with: jsonData, options: []) | ||
| return JSTypes.coerceDictionaryToJSObject( | ||
| (data as! NSDictionary), formattingDatesAsStrings: true)! | ||
| } | ||
|
|
||
| public func parseArgs<T: Decodable>(_ type: T.Type) throws -> T { | ||
| let jsonData = self.data.data(using: .utf8)! | ||
| let decoder = JSONDecoder() | ||
| decoder.userInfo[channelDataKey] = sendChannelData | ||
| return try decoder.decode(type, from: jsonData) | ||
| } | ||
|
|
||
| func serialize(_ data: JsonValue) -> String { | ||
| do { | ||
| return try data.jsonRepresentation() ?? "\"Failed to serialize payload\"" | ||
| } catch { | ||
| return "\"\(error)\"" | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
Resolved
|
||
| } | ||
|
|
||
| public func resolve() { | ||
| sendResponse(callback, nil) | ||
| } | ||
|
|
||
| public func resolve(_ data: JsonObject) { | ||
| resolve(.dictionary(data)) | ||
| } | ||
|
|
||
| public func resolve(_ data: JsonValue) { | ||
| sendResponse(callback, serialize(data)) | ||
| } | ||
|
|
||
| public func resolve<T: Encodable>(_ data: T) { | ||
| do { | ||
| let json = try JSONEncoder().encode(data) | ||
| sendResponse(callback, String(decoding: json, as: UTF8.self)) | ||
| } catch { | ||
| sendResponse(self.error, "\"\(error)\"") | ||
| } | ||
| } | ||
|
|
||
| public func reject( | ||
| _ message: String, code: String? = nil, error: Error? = nil, data: JsonValue? = nil | ||
| ) { | ||
| let payload: NSMutableDictionary = [ | ||
| "message": message | ||
| ] | ||
|
|
||
| if let code = code { | ||
| payload["code"] = code | ||
| } | ||
|
|
||
| if let error = error { | ||
| payload["error"] = error | ||
| } | ||
|
|
||
| if let data = data { | ||
| switch data { | ||
| case .dictionary(let dict): | ||
| for entry in dict { | ||
| payload[entry.key] = entry.value | ||
| } | ||
| } | ||
| } | ||
|
|
||
| sendResponse(self.error, serialize(.dictionary(payload as! JsonObject))) | ||
|
coderabbitai[bot] marked this conversation as resolved.
Resolved
|
||
| } | ||
|
|
||
| public func unimplemented() { | ||
| unimplemented("not implemented") | ||
| } | ||
|
|
||
| public func unimplemented(_ message: String) { | ||
| reject(message) | ||
| } | ||
|
|
||
| public func unavailable() { | ||
| unavailable("not available") | ||
| } | ||
|
|
||
| public func unavailable(_ message: String) { | ||
| reject(message) | ||
| } | ||
| } | ||
123 changes: 123 additions & 0 deletions
123
src-tauri/plugins/share-sheet/.tauri/tauri-api/Sources/Tauri/JSTypes.swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| // Copyright 2019-2024 Tauri Programme within The Commons Conservancy | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| import Foundation | ||
|
|
||
| // declare our empty protocol, and conformance, for typing | ||
| public protocol JSValue {} | ||
| extension String: JSValue {} | ||
| extension Bool: JSValue {} | ||
| extension Int: JSValue {} | ||
| extension Float: JSValue {} | ||
| extension Double: JSValue {} | ||
| extension NSNumber: JSValue {} | ||
| extension NSNull: JSValue {} | ||
| extension Array: JSValue {} | ||
| extension Date: JSValue {} | ||
| extension Dictionary: JSValue where Key == String, Value == JSValue {} | ||
|
|
||
| // convenience aliases | ||
| public typealias JSObject = [String: JSValue] | ||
| public typealias JSArray = [JSValue] | ||
|
|
||
| extension Dictionary where Key == String, Value == JSValue { | ||
| public func getValue(_ key: String) -> JSValue? { | ||
| return self[key] | ||
| } | ||
|
|
||
| public func getString(_ key: String) -> String? { | ||
| return self[key] as? String | ||
| } | ||
|
|
||
| public func getBool(_ key: String) -> Bool? { | ||
| return self[key] as? Bool | ||
| } | ||
|
|
||
| public func getInt(_ key: String) -> Int? { | ||
| return self[key] as? Int | ||
| } | ||
|
|
||
| public func getFloat(_ key: String) -> Float? { | ||
| if let floatValue = self[key] as? Float { | ||
| return floatValue | ||
| } else if let doubleValue = self[key] as? Double { | ||
| return Float(doubleValue) | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| public func getDouble(_ key: String) -> Double? { | ||
| return self[key] as? Double | ||
| } | ||
|
|
||
| public func getArray(_ key: String) -> JSArray? { | ||
| return self[key] as? JSArray | ||
| } | ||
|
|
||
| public func getObject(_ key: String) -> JSObject? { | ||
| return self[key] as? JSObject | ||
| } | ||
| } | ||
|
|
||
| /* | ||
| Simply casting objects from foundation class clusters (such as __NSArrayM) | ||
| doesn't work with the JSValue protocol and will always fail. So we need to | ||
| recursively and explicitly convert each value in the dictionary. | ||
| */ | ||
| public enum JSTypes {} | ||
| extension JSTypes { | ||
| public static func coerceDictionaryToJSObject( | ||
| _ dictionary: NSDictionary?, formattingDatesAsStrings: Bool = false | ||
| ) -> JSObject? { | ||
| return coerceToJSValue(dictionary, formattingDates: formattingDatesAsStrings) as? JSObject | ||
| } | ||
|
|
||
| public static func coerceDictionaryToJSObject( | ||
| _ dictionary: [AnyHashable: Any]?, formattingDatesAsStrings: Bool = false | ||
| ) -> JSObject? { | ||
| return coerceToJSValue(dictionary, formattingDates: formattingDatesAsStrings) as? JSObject | ||
| } | ||
| } | ||
|
|
||
| private let dateStringFormatter = ISO8601DateFormatter() | ||
|
|
||
| // We need a large switch statement because we have a lot of types. | ||
| // swiftlint:disable:next cyclomatic_complexity | ||
| private func coerceToJSValue(_ value: Any?, formattingDates: Bool) -> JSValue? { | ||
| guard let value = value else { | ||
| return nil | ||
| } | ||
| switch value { | ||
| case let stringValue as String: | ||
| return stringValue | ||
| case let numberValue as NSNumber: | ||
| return numberValue | ||
| case let boolValue as Bool: | ||
| return boolValue | ||
| case let intValue as Int: | ||
| return intValue | ||
| case let floatValue as Float: | ||
| return floatValue | ||
| case let doubleValue as Double: | ||
| return doubleValue | ||
| case let dateValue as Date: | ||
| if formattingDates { | ||
| return dateStringFormatter.string(from: dateValue) | ||
| } | ||
| return dateValue | ||
| case let nullValue as NSNull: | ||
| return nullValue | ||
| case let arrayValue as NSArray: | ||
| return arrayValue.compactMap { coerceToJSValue($0, formattingDates: formattingDates) } | ||
| case let dictionaryValue as NSDictionary: | ||
| let keys = dictionaryValue.allKeys.compactMap { $0 as? String } | ||
| var result: JSObject = [:] | ||
| for key in keys { | ||
| result[key] = coerceToJSValue(dictionaryValue[key], formattingDates: formattingDates) | ||
| } | ||
| return result | ||
| default: | ||
| return nil | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.