diff --git a/changelogs/v0-50-3.md b/changelogs/v0-50-3.md
new file mode 100644
index 00000000..f4ae6faf
--- /dev/null
+++ b/changelogs/v0-50-3.md
@@ -0,0 +1,17 @@
+* [+10/-10][app | chat_server | comty.js | file_server | marketplace_server | music_server | server | wrapper] [Bump version to 0.50.3](https://github.com/ragestudio/comty/commit/ae985c4960742e8df318871493148e487cad9943) - by [@SrGooglo](https://github.com/srgooglo)
+
+* [+2/-1][app] [added `lru-cache`](https://github.com/ragestudio/comty/commit/2dfcd945d64f2598e95ba09e96c36dd617ad76cf) - by [@SrGooglo](https://github.com/srgooglo)
+
+* [+7/-1][app] [set `latencyHint` to `playback`](https://github.com/ragestudio/comty/commit/fcef9a9683426d2acef7dbfb4b3c0350846b7a3e) - by [@SrGooglo](https://github.com/srgooglo)
+
+* [+7/-6][app] [filter non numbers values](https://github.com/ragestudio/comty/commit/7d13c94cfbba56d9bcf779bae140b9e06017a3b2) - by [@SrGooglo](https://github.com/srgooglo)
+
+* [+9/-2][app] [added `usePadding` option](https://github.com/ragestudio/comty/commit/42548d2af718c57fa675862790a38cb8e26c2041) - by [@SrGooglo](https://github.com/srgooglo)
+
+* [+17/-10][app] [improve label display](https://github.com/ragestudio/comty/commit/e5fdc90a9ee26486d7c1a310e78793111188bdd6) - by [@SrGooglo](https://github.com/srgooglo)
+
+* [+11/-2][app] [add step && marks](https://github.com/ragestudio/comty/commit/76dd480254282f98678a1d081fc1b6651a03207c) - by [@SrGooglo](https://github.com/srgooglo)
+
+* [+1/-1][app] [decrease default sample rate to `48000` to avoid device related issues](https://github.com/ragestudio/comty/commit/e1ef3ff2ac109d9674137dbbf99cf1aba729ad31) - by [@SrGooglo](https://github.com/srgooglo)
+
+* [+31/-0][v0-50-2.md] [added changelog](https://github.com/ragestudio/comty/commit/e339c98986a8ce6fb6366272dbcaa1f29bb797e8) - by [@SrGooglo](https://github.com/srgooglo)
\ No newline at end of file
diff --git a/package.json b/package.json
index 65e20846..252bbee0 100755
--- a/package.json
+++ b/package.json
@@ -31,5 +31,5 @@
"form-data": "^4.0.0",
"pm2": "5.3.0"
},
- "version": "0.50.3"
+ "version": "0.50.4"
}
\ No newline at end of file
diff --git a/packages/app/constants/settings/about/index.jsx b/packages/app/constants/settings/about/index.jsx
index 51caafc7..ada173a6 100755
--- a/packages/app/constants/settings/about/index.jsx
+++ b/packages/app/constants/settings/about/index.jsx
@@ -70,6 +70,15 @@ export default {
const [serverHealth, setServerHealth] = React.useState(null)
const [secureConnection, setSecureConnection] = React.useState(false)
const [connectionPing, setConnectionPing] = React.useState({})
+ const [capInfo, setCapInfo] = React.useState(null)
+
+ const setCapacitorInfo = async () => {
+ if (Capacitor.Plugins.App) {
+ const info = await Capacitor.Plugins.App.getInfo()
+
+ setCapInfo(info)
+ }
+ }
const checkServerVersion = async () => {
const serverManifest = await app.cores.api.customRequest()
@@ -117,6 +126,8 @@ export default {
fetchServerHealth()
measurePing()
+ setCapacitorInfo()
+
const measureInterval = setInterval(() => {
fetchServerHealth()
measurePing()
@@ -191,6 +202,8 @@ export default {
alignItems: "center",
gap: "0.5rem",
fontSize: "1.4rem",
+ justifyContent: "space-evenly",
+ width: "100%",
}}
>
+
+ {
+ capInfo &&
+ }
+
+ {
+ capInfo &&
+
+
+
+ {capInfo.build}
+
+
+ }
+
+ {
+ capInfo &&
+
+
+
+ {capInfo.version}
+
+
+ }
}
diff --git a/packages/app/package.json b/packages/app/package.json
index c8bcbe06..cd5a9906 100755
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -1,6 +1,6 @@
{
"name": "@comty/web-app",
- "version": "0.50.3",
+ "version": "0.50.4",
"license": "LGPL-2.1",
"main": "electron/main",
"author": "RageStudio",
@@ -51,6 +51,7 @@
"antd-mobile": "^5.31.0",
"axios": "^1.4.0",
"buffer": "^6.0.3",
+ "capacitor-music-controls-plugin-v3": "^1.1.0",
"classnames": "2.3.1",
"dexie": "^3.2.3",
"dompurify": "^3.0.0",
diff --git a/packages/app/src/cores/player/player.core.js b/packages/app/src/cores/player/player.core.js
index 175797f4..1a5abb01 100755
--- a/packages/app/src/cores/player/player.core.js
+++ b/packages/app/src/cores/player/player.core.js
@@ -1,6 +1,8 @@
import Core from "evite/src/core"
import { Observable } from "object-observer"
import { FastAverageColor } from "fast-average-color"
+import { CapacitorMusicControls } from 'capacitor-music-controls-plugin-v3'
+
//import { LRUCache } from "lru-cache/dist/mjs/index"
import PlaylistModel from "comty.js/models/playlists"
@@ -34,6 +36,125 @@ const defaultAudioProccessors = [
CompressorProcessorNode,
]
+class MediaSession {
+ initialize() {
+ CapacitorMusicControls.addListener("controlsNotification", (info) => {
+ console.log(info)
+
+ this.handleControlsEvent(info)
+ })
+
+ // ANDROID (13, see bug above as to why it's necessary)
+ document.addEventListener("controlsNotification", (event) => {
+ console.log(event)
+
+ const info = { message: event.message, position: 0 }
+
+ this.handleControlsEvent(info)
+ })
+ }
+
+ update(manifest) {
+ if ("mediaSession" in navigator) {
+ return navigator.mediaSession.metadata = new MediaMetadata({
+ title: manifest.title,
+ artist: manifest.artist,
+ album: manifest.album,
+ artwork: [
+ {
+ src: manifest.cover ?? manifest.thumbnail,
+ sizes: "512x512",
+ type: "image/jpeg",
+ }
+ ],
+ })
+ }
+
+ return CapacitorMusicControls.create({
+ track: manifest.title,
+ artist: manifest.artist,
+ album: manifest.album,
+ cover: manifest.cover,
+
+ hasPrev: false,
+ hasNext: false,
+ hasClose: true,
+
+ isPlaying: true,
+ dismissable: false,
+
+ playIcon: "media_play",
+ pauseIcon: "media_pause",
+ prevIcon: "media_prev",
+ nextIcon: "media_next",
+ closeIcon: "media_close",
+ notificationIcon: "notification"
+ })
+ }
+
+ updateIsPlaying(to, timeElapsed = 0) {
+ if ("mediaSession" in navigator) {
+ return navigator.mediaSession.playbackState = to ? "playing" : "paused"
+ }
+
+ return CapacitorMusicControls.updateIsPlaying({
+ isPlaying: to,
+ elapsed: timeElapsed,
+ })
+ }
+
+ destroy() {
+ if ("mediaSession" in navigator) {
+ navigator.mediaSession.playbackState = "none"
+ }
+
+ this.active = false
+
+ return CapacitorMusicControls.destroy()
+ }
+
+ handleControlsEvent(action) {
+ const message = action.message
+
+ switch (message) {
+ case "music-controls-next": {
+ return app.cores.player.playback.next()
+ }
+ case "music-controls-previous": {
+ return app.cores.player.playback.previous()
+ }
+ case "music-controls-pause": {
+ return app.cores.player.playback.pause()
+ }
+ case "music-controls-play": {
+ return app.cores.player.playback.play()
+ }
+ case "music-controls-destroy": {
+ return app.cores.player.playback.stop()
+ }
+
+ // External controls (iOS only)
+ case "music-controls-toggle-play-pause": {
+ return app.cores.player.playback.toogle()
+ }
+
+ // Headset events (Android only)
+ // All media button events are listed below
+ case "music-controls-media-button": {
+ return app.cores.player.playback.toogle()
+ }
+ case "music-controls-headset-unplugged": {
+ return app.cores.player.playback.pause()
+ }
+ case "music-controls-headset-plugged": {
+ return app.cores.player.playback.play()
+ }
+ default:
+ break;
+ }
+ }
+}
+
// TODO: Check if source playing is a stream. Also handle if it's a stream resuming after a pause will seek to the last position
export default class Player extends Core {
static dependencies = [
@@ -49,6 +170,8 @@ export default class Player extends Core {
static defaultSampleRate = 48000
+ native_controls = new MediaSession()
+
currentDomWindow = null
audioContext = new AudioContext({
@@ -370,6 +493,7 @@ export default class Player extends Core {
async onInitialize() {
this.initializeAudioProcessors()
this.observeStateChanges()
+ this.native_controls.initialize()
}
async initializeBeforeRuntimeInitialize() {
@@ -646,7 +770,6 @@ export default class Player extends Core {
// storage media data on browser cache to improve performance
instanceObj.media.data = instanceObj.audioElement
-
return instanceObj
}
@@ -736,33 +859,12 @@ export default class Player extends Core {
instance.audioElement.play()
// set navigator metadata
- if ("mediaSession" in navigator) {
- navigator.mediaSession.metadata = new MediaMetadata({
- title: instance.manifest.title,
- artist: instance.manifest.artist,
- album: instance.manifest.album,
- artwork: [
- {
- src: instance.manifest.cover ?? instance.manifest.thumbnail,
- sizes: "512x512",
- type: "image/jpeg",
- }
- ],
- })
- }
+ this.native_controls.update(instance.manifest)
// check if the audio is a live stream when metadata is loaded
instance.audioElement.addEventListener("loadedmetadata", () => {
console.log("loadedmetadata", instance.audioElement.duration)
- // if ("mediaSesion" in navigator) {
- // navigator.mediaSession.setPositionState({
- // duration: instance.audioElement.duration,
- // playbackRate: instance.audioElement.playbackRate,
- // position: instance.audioElement.currentTime,
- // })
- // }
-
if (instance.audioElement.duration === Infinity) {
instance.manifest.stream = true
@@ -923,9 +1025,7 @@ export default class Player extends Core {
resolve()
}, gradualFadeMs)
- if ("mediaSession" in navigator) {
- navigator.mediaSession.playbackState = "paused"
- }
+ this.native_controls.updateIsPlaying(false)
})
}
@@ -949,9 +1049,7 @@ export default class Player extends Core {
this.audioContext.currentTime + (gradualFadeMs / 1000)
)
- if ("mediaSession" in navigator) {
- navigator.mediaSession.playbackState = "playing"
- }
+ this.native_controls.updateIsPlaying(true)
})
}
@@ -967,9 +1065,7 @@ export default class Player extends Core {
this.audioQueue = []
- if ("mediaSession" in navigator) {
- navigator.mediaSession.playbackState = "none"
- }
+ this.native_controls.destroy()
}
close() {
diff --git a/packages/chat_server/package.json b/packages/chat_server/package.json
index c48983e4..740c9adc 100755
--- a/packages/chat_server/package.json
+++ b/packages/chat_server/package.json
@@ -1,6 +1,6 @@
{
"name": "@comty/chat_server",
- "version": "0.50.3",
+ "version": "0.50.4",
"main": "dist/index.js",
"scripts": {
"build": "corenode-cli build",
diff --git a/packages/comty.js/package.json b/packages/comty.js/package.json
index 2342a72e..51e2f03b 100644
--- a/packages/comty.js/package.json
+++ b/packages/comty.js/package.json
@@ -1,6 +1,6 @@
{
"name": "comty.js",
- "version": "0.50.3",
+ "version": "0.50.4",
"main": "./dist/index.js",
"author": "RageStudio ",
"scripts": {
diff --git a/packages/file_server/package.json b/packages/file_server/package.json
index 1139d3e3..2eea3e79 100644
--- a/packages/file_server/package.json
+++ b/packages/file_server/package.json
@@ -1,6 +1,6 @@
{
"name": "@comty/file_server",
- "version": "0.50.3",
+ "version": "0.50.4",
"main": "dist/index.js",
"scripts": {
"build": "corenode-cli build",
diff --git a/packages/marketplace_server/package.json b/packages/marketplace_server/package.json
index 903cc2b2..8b3bb36a 100644
--- a/packages/marketplace_server/package.json
+++ b/packages/marketplace_server/package.json
@@ -1,6 +1,6 @@
{
"name": "@comty/marketplace_server",
- "version": "0.50.3",
+ "version": "0.50.4",
"main": "dist/index.js",
"scripts": {
"build": "corenode-cli build",
diff --git a/packages/music_server/package.json b/packages/music_server/package.json
index cd15d31b..76fcfa97 100644
--- a/packages/music_server/package.json
+++ b/packages/music_server/package.json
@@ -1,6 +1,6 @@
{
"name": "@comty/music_server",
- "version": "0.50.3",
+ "version": "0.50.4",
"main": "dist/index.js",
"scripts": {
"build": "corenode-cli build",
diff --git a/packages/server/package.json b/packages/server/package.json
index 1e1f1fb8..c0731ae6 100755
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -1,6 +1,6 @@
{
"name": "@comty/server",
- "version": "0.50.3",
+ "version": "0.50.4",
"main": "dist/index.js",
"scripts": {
"build": "corenode-cli build",
diff --git a/packages/wrapper/package.json b/packages/wrapper/package.json
index 59b958bd..d4ce2734 100755
--- a/packages/wrapper/package.json
+++ b/packages/wrapper/package.json
@@ -1,6 +1,6 @@
{
"name": "@comty/web-wrapper",
- "version": "0.50.3",
+ "version": "0.50.4",
"main": "./src/index.js",
"license": "MIT",
"scripts": {