@capawesome/capacitor-volume 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CapawesomeCapacitorVolume.podspec +17 -0
- package/LICENSE +21 -0
- package/Package.swift +28 -0
- package/README.md +405 -0
- package/android/build.gradle +58 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/Volume.java +158 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/VolumeHelper.java +27 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/VolumePlugin.java +178 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/classes/CustomException.java +20 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/classes/CustomExceptions.java +12 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/classes/events/VolumeButtonPressedEvent.java +23 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/classes/events/VolumeChangeEvent.java +22 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/classes/options/GetVolumeOptions.java +23 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/classes/options/SetVolumeOptions.java +41 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/classes/options/StartWatchingOptions.java +17 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/classes/results/GetVolumeResult.java +22 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/classes/results/IsWatchingResult.java +22 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/interfaces/Callback.java +5 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/interfaces/EmptyCallback.java +5 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/interfaces/NonEmptyResultCallback.java +7 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/volume/interfaces/Result.java +7 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +540 -0
- package/dist/esm/definitions.d.ts +255 -0
- package/dist/esm/definitions.js +60 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +9 -0
- package/dist/esm/web.js +19 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +93 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +96 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/Classes/Events/VolumeButtonPressedEvent.swift +16 -0
- package/ios/Plugin/Classes/Events/VolumeChangeEvent.swift +16 -0
- package/ios/Plugin/Classes/Options/SetVolumeOptions.swift +20 -0
- package/ios/Plugin/Classes/Options/StartWatchingOptions.swift +10 -0
- package/ios/Plugin/Classes/Results/GetVolumeResult.swift +16 -0
- package/ios/Plugin/Classes/Results/IsWatchingResult.swift +16 -0
- package/ios/Plugin/Enums/CustomError.swift +24 -0
- package/ios/Plugin/Info.plist +24 -0
- package/ios/Plugin/Protocols/Result.swift +5 -0
- package/ios/Plugin/Volume.swift +192 -0
- package/ios/Plugin/VolumePlugin.swift +109 -0
- package/package.json +91 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
|
|
4
|
+
@objc public class IsWatchingResult: NSObject, Result {
|
|
5
|
+
let watching: Bool
|
|
6
|
+
|
|
7
|
+
init(watching: Bool) {
|
|
8
|
+
self.watching = watching
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
@objc public func toJSObject() -> AnyObject {
|
|
12
|
+
var result = JSObject()
|
|
13
|
+
result["watching"] = watching
|
|
14
|
+
return result as AnyObject
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
enum CustomError: Error {
|
|
4
|
+
case volumeInvalid
|
|
5
|
+
case volumeMissing
|
|
6
|
+
|
|
7
|
+
var code: String? {
|
|
8
|
+
switch self {
|
|
9
|
+
case .volumeInvalid, .volumeMissing:
|
|
10
|
+
return nil
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
extension CustomError: LocalizedError {
|
|
16
|
+
public var errorDescription: String? {
|
|
17
|
+
switch self {
|
|
18
|
+
case .volumeInvalid:
|
|
19
|
+
return NSLocalizedString("volume must be between 0 and 1.", comment: "volumeInvalid")
|
|
20
|
+
case .volumeMissing:
|
|
21
|
+
return NSLocalizedString("volume must be provided.", comment: "volumeMissing")
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>CFBundleDevelopmentRegion</key>
|
|
6
|
+
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
|
7
|
+
<key>CFBundleExecutable</key>
|
|
8
|
+
<string>$(EXECUTABLE_NAME)</string>
|
|
9
|
+
<key>CFBundleIdentifier</key>
|
|
10
|
+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
11
|
+
<key>CFBundleInfoDictionaryVersion</key>
|
|
12
|
+
<string>6.0</string>
|
|
13
|
+
<key>CFBundleName</key>
|
|
14
|
+
<string>$(PRODUCT_NAME)</string>
|
|
15
|
+
<key>CFBundlePackageType</key>
|
|
16
|
+
<string>FMWK</string>
|
|
17
|
+
<key>CFBundleShortVersionString</key>
|
|
18
|
+
<string>1.0</string>
|
|
19
|
+
<key>CFBundleVersion</key>
|
|
20
|
+
<string>$(CURRENT_PROJECT_VERSION)</string>
|
|
21
|
+
<key>NSPrincipalClass</key>
|
|
22
|
+
<string></string>
|
|
23
|
+
</dict>
|
|
24
|
+
</plist>
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import AVFoundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
import Foundation
|
|
4
|
+
import MediaPlayer
|
|
5
|
+
import UIKit
|
|
6
|
+
|
|
7
|
+
@objc public class Volume: NSObject {
|
|
8
|
+
private static let directionDown = "down"
|
|
9
|
+
private static let directionUp = "up"
|
|
10
|
+
private static let maximumSuppressedVolume: Float = 0.875
|
|
11
|
+
private static let minimumSuppressedVolume: Float = 0.125
|
|
12
|
+
private static let minimumVolumeDelta: Float = 0.001
|
|
13
|
+
private static let programmaticChangeTolerance: Float = 0.05
|
|
14
|
+
private static let sliderSetDelay: TimeInterval = 0.1
|
|
15
|
+
private static let volumeViewRemovalDelay: TimeInterval = 0.5
|
|
16
|
+
|
|
17
|
+
private let audioSession = AVAudioSession.sharedInstance()
|
|
18
|
+
private let plugin: VolumePlugin
|
|
19
|
+
|
|
20
|
+
private var initialVolume: Float = 0
|
|
21
|
+
private var lastVolume: Float = 0
|
|
22
|
+
private var pendingSetVolume: Float?
|
|
23
|
+
private var suppressVolumeChange = false
|
|
24
|
+
private var volumeObservation: NSKeyValueObservation?
|
|
25
|
+
private var volumeView: MPVolumeView?
|
|
26
|
+
private var watching = false
|
|
27
|
+
|
|
28
|
+
init(plugin: VolumePlugin) {
|
|
29
|
+
self.plugin = plugin
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
deinit {
|
|
33
|
+
volumeObservation?.invalidate()
|
|
34
|
+
NotificationCenter.default.removeObserver(self)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@objc public func getVolume(completion: @escaping (_ result: GetVolumeResult?, _ error: Error?) -> Void) {
|
|
38
|
+
try? activateAudioSession()
|
|
39
|
+
completion(GetVolumeResult(volume: audioSession.outputVolume), nil)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@objc public func isWatching(completion: @escaping (_ result: IsWatchingResult?, _ error: Error?) -> Void) {
|
|
43
|
+
DispatchQueue.main.async {
|
|
44
|
+
completion(IsWatchingResult(watching: self.watching), nil)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@objc public func setVolume(_ options: SetVolumeOptions, completion: @escaping (_ error: Error?) -> Void) {
|
|
49
|
+
DispatchQueue.main.async {
|
|
50
|
+
self.setSystemVolume(options.volume)
|
|
51
|
+
completion(nil)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@objc public func startWatching(_ options: StartWatchingOptions, completion: @escaping (_ error: Error?) -> Void) {
|
|
56
|
+
DispatchQueue.main.async {
|
|
57
|
+
if self.watching {
|
|
58
|
+
completion(nil)
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
do {
|
|
62
|
+
try self.activateAudioSession()
|
|
63
|
+
} catch {
|
|
64
|
+
completion(error)
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
self.suppressVolumeChange = options.suppressVolumeChange
|
|
68
|
+
self.initialVolume = self.audioSession.outputVolume
|
|
69
|
+
self.lastVolume = self.initialVolume
|
|
70
|
+
self.watching = true
|
|
71
|
+
if self.suppressVolumeChange {
|
|
72
|
+
self.addVolumeView()
|
|
73
|
+
self.applySuppressedVolume(self.initialVolume)
|
|
74
|
+
}
|
|
75
|
+
self.volumeObservation = self.audioSession.observe(\.outputVolume, options: [.new]) { [weak self] _, change in
|
|
76
|
+
guard let newVolume = change.newValue else {
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
DispatchQueue.main.async {
|
|
80
|
+
self?.handleVolumeChanged(newVolume)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
NotificationCenter.default.addObserver(
|
|
84
|
+
self,
|
|
85
|
+
selector: #selector(self.handleDidBecomeActive),
|
|
86
|
+
name: UIApplication.didBecomeActiveNotification,
|
|
87
|
+
object: nil
|
|
88
|
+
)
|
|
89
|
+
completion(nil)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@objc public func stopWatching(completion: ((_ error: Error?) -> Void)? = nil) {
|
|
94
|
+
DispatchQueue.main.async {
|
|
95
|
+
if !self.watching {
|
|
96
|
+
completion?(nil)
|
|
97
|
+
return
|
|
98
|
+
}
|
|
99
|
+
self.volumeObservation?.invalidate()
|
|
100
|
+
self.volumeObservation = nil
|
|
101
|
+
NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
|
|
102
|
+
self.watching = false
|
|
103
|
+
if self.suppressVolumeChange {
|
|
104
|
+
self.suppressVolumeChange = false
|
|
105
|
+
self.setSystemVolume(self.initialVolume)
|
|
106
|
+
}
|
|
107
|
+
self.pendingSetVolume = nil
|
|
108
|
+
try? self.audioSession.setActive(false, options: .notifyOthersOnDeactivation)
|
|
109
|
+
completion?(nil)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private func activateAudioSession() throws {
|
|
114
|
+
try audioSession.setCategory(.ambient, options: .mixWithOthers)
|
|
115
|
+
try audioSession.setActive(true)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private func addVolumeView() {
|
|
119
|
+
guard volumeView == nil else {
|
|
120
|
+
return
|
|
121
|
+
}
|
|
122
|
+
let volumeView = MPVolumeView(frame: CGRect(x: -3000, y: -3000, width: 100, height: 100))
|
|
123
|
+
plugin.bridge?.viewController?.view.addSubview(volumeView)
|
|
124
|
+
self.volumeView = volumeView
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private func applySuppressedVolume(_ volume: Float) {
|
|
128
|
+
let suppressedVolume = min(max(volume, Self.minimumSuppressedVolume), Self.maximumSuppressedVolume)
|
|
129
|
+
if suppressedVolume != volume {
|
|
130
|
+
setSystemVolume(suppressedVolume)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@objc private func handleDidBecomeActive() {
|
|
135
|
+
try? activateAudioSession()
|
|
136
|
+
lastVolume = audioSession.outputVolume
|
|
137
|
+
if suppressVolumeChange {
|
|
138
|
+
applySuppressedVolume(lastVolume)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private func handleVolumeChanged(_ newVolume: Float) {
|
|
143
|
+
if let pendingSetVolume = pendingSetVolume, abs(newVolume - pendingSetVolume) < Self.programmaticChangeTolerance {
|
|
144
|
+
self.pendingSetVolume = nil
|
|
145
|
+
let changed = abs(newVolume - lastVolume) >= Self.minimumVolumeDelta
|
|
146
|
+
lastVolume = newVolume
|
|
147
|
+
if changed && !suppressVolumeChange {
|
|
148
|
+
plugin.notifyVolumeChangeListeners(VolumeChangeEvent(volume: newVolume))
|
|
149
|
+
}
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
let delta = newVolume - lastVolume
|
|
153
|
+
if abs(delta) < Self.minimumVolumeDelta {
|
|
154
|
+
return
|
|
155
|
+
}
|
|
156
|
+
let direction = delta > 0 ? Self.directionUp : Self.directionDown
|
|
157
|
+
plugin.notifyVolumeButtonPressedListeners(VolumeButtonPressedEvent(direction: direction))
|
|
158
|
+
if suppressVolumeChange {
|
|
159
|
+
setSystemVolume(lastVolume)
|
|
160
|
+
} else {
|
|
161
|
+
lastVolume = newVolume
|
|
162
|
+
plugin.notifyVolumeChangeListeners(VolumeChangeEvent(volume: newVolume))
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
private func removeVolumeView() {
|
|
167
|
+
volumeView?.removeFromSuperview()
|
|
168
|
+
volumeView = nil
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private func setSystemVolume(_ volume: Float) {
|
|
172
|
+
addVolumeView()
|
|
173
|
+
if watching {
|
|
174
|
+
pendingSetVolume = volume
|
|
175
|
+
}
|
|
176
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + Self.sliderSetDelay) { [weak self] in
|
|
177
|
+
guard let self = self else {
|
|
178
|
+
return
|
|
179
|
+
}
|
|
180
|
+
let slider = self.volumeView?.subviews.compactMap { $0 as? UISlider }.first
|
|
181
|
+
slider?.value = volume
|
|
182
|
+
if !(self.watching && self.suppressVolumeChange) {
|
|
183
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + Self.volumeViewRemovalDelay) { [weak self] in
|
|
184
|
+
guard let self = self, !(self.watching && self.suppressVolumeChange) else {
|
|
185
|
+
return
|
|
186
|
+
}
|
|
187
|
+
self.removeVolumeView()
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
|
|
4
|
+
@objc(VolumePlugin)
|
|
5
|
+
public class VolumePlugin: CAPPlugin, CAPBridgedPlugin {
|
|
6
|
+
public let identifier = "VolumePlugin"
|
|
7
|
+
public let jsName = "Volume"
|
|
8
|
+
public let pluginMethods: [CAPPluginMethod] = [
|
|
9
|
+
CAPPluginMethod(name: "getVolume", returnType: CAPPluginReturnPromise),
|
|
10
|
+
CAPPluginMethod(name: "isWatching", returnType: CAPPluginReturnPromise),
|
|
11
|
+
CAPPluginMethod(name: "setVolume", returnType: CAPPluginReturnPromise),
|
|
12
|
+
CAPPluginMethod(name: "startWatching", returnType: CAPPluginReturnPromise),
|
|
13
|
+
CAPPluginMethod(name: "stopWatching", returnType: CAPPluginReturnPromise)
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
public static let eventVolumeButtonPressed = "volumeButtonPressed"
|
|
17
|
+
public static let eventVolumeChange = "volumeChange"
|
|
18
|
+
public static let tag = "VolumePlugin"
|
|
19
|
+
|
|
20
|
+
private var implementation: Volume?
|
|
21
|
+
|
|
22
|
+
@objc func getVolume(_ call: CAPPluginCall) {
|
|
23
|
+
implementation?.getVolume(completion: { result, error in
|
|
24
|
+
if let error = error {
|
|
25
|
+
self.rejectCall(call, error)
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
self.resolveCall(call, result)
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@objc func isWatching(_ call: CAPPluginCall) {
|
|
33
|
+
implementation?.isWatching(completion: { result, error in
|
|
34
|
+
if let error = error {
|
|
35
|
+
self.rejectCall(call, error)
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
self.resolveCall(call, result)
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
override public func load() {
|
|
43
|
+
self.implementation = Volume(plugin: self)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@objc public func notifyVolumeButtonPressedListeners(_ event: VolumeButtonPressedEvent) {
|
|
47
|
+
self.notifyListeners(Self.eventVolumeButtonPressed, data: event.toJSObject() as? [String: Any])
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@objc public func notifyVolumeChangeListeners(_ event: VolumeChangeEvent) {
|
|
51
|
+
self.notifyListeners(Self.eventVolumeChange, data: event.toJSObject() as? [String: Any])
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@objc func setVolume(_ call: CAPPluginCall) {
|
|
55
|
+
do {
|
|
56
|
+
let options = try SetVolumeOptions(call)
|
|
57
|
+
|
|
58
|
+
implementation?.setVolume(options, completion: { error in
|
|
59
|
+
if let error = error {
|
|
60
|
+
self.rejectCall(call, error)
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
self.resolveCall(call)
|
|
64
|
+
})
|
|
65
|
+
} catch {
|
|
66
|
+
rejectCall(call, error)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@objc func startWatching(_ call: CAPPluginCall) {
|
|
71
|
+
let options = StartWatchingOptions(call)
|
|
72
|
+
|
|
73
|
+
implementation?.startWatching(options, completion: { error in
|
|
74
|
+
if let error = error {
|
|
75
|
+
self.rejectCall(call, error)
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
self.resolveCall(call)
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@objc func stopWatching(_ call: CAPPluginCall) {
|
|
83
|
+
implementation?.stopWatching { error in
|
|
84
|
+
if let error = error {
|
|
85
|
+
self.rejectCall(call, error)
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
self.resolveCall(call)
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private func rejectCall(_ call: CAPPluginCall, _ error: Error) {
|
|
93
|
+
CAPLog.print("[", VolumePlugin.tag, "] ", error)
|
|
94
|
+
let code = (error as? CustomError)?.code
|
|
95
|
+
call.reject(error.localizedDescription, code)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private func resolveCall(_ call: CAPPluginCall) {
|
|
99
|
+
call.resolve()
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private func resolveCall(_ call: CAPPluginCall, _ result: Result?) {
|
|
103
|
+
if let result = result?.toJSObject() as? JSObject {
|
|
104
|
+
call.resolve(result)
|
|
105
|
+
} else {
|
|
106
|
+
call.resolve()
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@capawesome/capacitor-volume",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Capacitor plugin to control the volume and observe hardware volume button presses.",
|
|
5
|
+
"main": "dist/plugin.cjs.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"types": "dist/esm/index.d.ts",
|
|
8
|
+
"unpkg": "dist/plugin.js",
|
|
9
|
+
"files": [
|
|
10
|
+
"android/src/main/",
|
|
11
|
+
"android/build.gradle",
|
|
12
|
+
"dist/",
|
|
13
|
+
"ios/Plugin/",
|
|
14
|
+
"CapawesomeCapacitorVolume.podspec",
|
|
15
|
+
"Package.swift"
|
|
16
|
+
],
|
|
17
|
+
"author": "Robin Genz <mail@robingenz.dev>",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/capawesome-team/capacitor-plugins.git"
|
|
22
|
+
},
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/capawesome-team/capacitor-plugins/issues"
|
|
25
|
+
},
|
|
26
|
+
"funding": [
|
|
27
|
+
{
|
|
28
|
+
"type": "github",
|
|
29
|
+
"url": "https://github.com/sponsors/capawesome-team/"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": "opencollective",
|
|
33
|
+
"url": "https://opencollective.com/capawesome"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"homepage": "https://capawesome.io/docs/plugins/volume/",
|
|
37
|
+
"keywords": [
|
|
38
|
+
"capacitor",
|
|
39
|
+
"plugin",
|
|
40
|
+
"native"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
|
|
44
|
+
"verify:ios": "cd ios && pod install && xcodebuild -workspace Plugin.xcworkspace -scheme Plugin -destination generic/platform=iOS && cd ..",
|
|
45
|
+
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
|
46
|
+
"verify:web": "npm run build",
|
|
47
|
+
"lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
|
|
48
|
+
"fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
|
|
49
|
+
"eslint": "eslint . --ext ts",
|
|
50
|
+
"prettier": "prettier \"**/*.{css,html,ts,js,java}\"",
|
|
51
|
+
"swiftlint": "node-swiftlint",
|
|
52
|
+
"docgen": "docgen --api VolumePlugin --output-readme README.md --output-json dist/docs.json",
|
|
53
|
+
"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
|
|
54
|
+
"clean": "rimraf ./dist",
|
|
55
|
+
"watch": "tsc --watch",
|
|
56
|
+
"ios:pod:install": "cd ios && pod install --repo-update && cd ..",
|
|
57
|
+
"ios:spm:install": "cd ios && swift package resolve && cd ..",
|
|
58
|
+
"prepublishOnly": "npm run build"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@capacitor/android": "8.0.0",
|
|
62
|
+
"@capacitor/cli": "8.0.0",
|
|
63
|
+
"@capacitor/core": "8.0.0",
|
|
64
|
+
"@capacitor/docgen": "0.3.1",
|
|
65
|
+
"@capacitor/ios": "8.0.0",
|
|
66
|
+
"@ionic/eslint-config": "0.4.0",
|
|
67
|
+
"eslint": "8.57.0",
|
|
68
|
+
"prettier-plugin-java": "2.6.7",
|
|
69
|
+
"rimraf": "6.1.2",
|
|
70
|
+
"rollup": "4.53.3",
|
|
71
|
+
"swiftlint": "2.0.0",
|
|
72
|
+
"typescript": "5.9.3"
|
|
73
|
+
},
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"@capacitor/core": ">=8.0.0"
|
|
76
|
+
},
|
|
77
|
+
"eslintConfig": {
|
|
78
|
+
"extends": "@ionic/eslint-config/recommended"
|
|
79
|
+
},
|
|
80
|
+
"capacitor": {
|
|
81
|
+
"ios": {
|
|
82
|
+
"src": "ios"
|
|
83
|
+
},
|
|
84
|
+
"android": {
|
|
85
|
+
"src": "android"
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"publishConfig": {
|
|
89
|
+
"access": "public"
|
|
90
|
+
}
|
|
91
|
+
}
|