15 changed files with 567 additions and 91 deletions
-
8kplayer.xcodeproj/project.pbxproj
-
3kplayer/AppDelegate.swift
-
35kplayer/core/DatabaseManager.swift
-
2kplayer/core/MediaItem.swift
-
119kplayer/core/NetworkManager.swift
-
2kplayer/detail/EditItemView.swift
-
6kplayer/detail/ItemCell.swift
-
10kplayer/master/KSettingsView.swift
-
2kplayer/master/NetworkDelegate.swift
-
2kplayer/master/SearchItemView.swift
-
74kplayer/server/kplayer.js
-
54kplayer/server/raspberrypi.js
-
135kplayer/video/SRangeSlider.swift
-
104kplayer/video/SVideoPlayer.swift
-
22kplayer/video/VideoPlayerView.swift
@ -0,0 +1,54 @@ |
|||
// pm2 restart kplayer
|
|||
// /srv/samba/daten/node
|
|||
|
|||
var express = require('express'); |
|||
var fs = require("fs"); |
|||
var path = require("path"); |
|||
|
|||
const { exec, execSync} = require('child_process'); |
|||
|
|||
var app = express(); |
|||
|
|||
app.get('/', function(req, res) { |
|||
res.json({ message: 'WELCOME' }); |
|||
}); |
|||
|
|||
app.get('/wakelinkstation', function (req, res) { |
|||
var cmd = '/srv/raspi/bin/wakeup-linkstation.sh' |
|||
console.log(cmd) |
|||
exec(cmd, (err, stdout, stderr) => { |
|||
if (err) { |
|||
console.log(err) |
|||
// node couldn't execute the command
|
|||
return; |
|||
} |
|||
|
|||
// the *entire* stdout and stderr (buffered)
|
|||
console.log(`stdout: ${stdout}`); |
|||
console.log(`stderr: ${stderr}`); |
|||
}); |
|||
res.send("ok") |
|||
}) |
|||
|
|||
app.get('/suspendlinkstation', function (req, res) { |
|||
var cmd = '/srv/raspi/bin/suspend-linkstation.sh' |
|||
console.log(cmd) |
|||
exec(cmd, (err, stdout, stderr) => { |
|||
if (err) { |
|||
console.log(err) |
|||
// node couldn't execute the command
|
|||
return; |
|||
} |
|||
|
|||
// the *entire* stdout and stderr (buffered)
|
|||
console.log(`stdout: ${stdout}`); |
|||
console.log(`stderr: ${stderr}`); |
|||
}); |
|||
res.send("ok") |
|||
}) |
|||
|
|||
var server = app.listen(8081, function () { |
|||
var host = server.address().address |
|||
var port = server.address().port |
|||
console.log("Server listening at http://%s:%s", host, port) |
|||
}) |
|||
@ -0,0 +1,135 @@ |
|||
// |
|||
// Created by Marco Schmickler on 25.12.22. |
|||
// Copyright (c) 2022 Marco Schmickler. All rights reserved. |
|||
// |
|||
|
|||
import Foundation |
|||
import SwiftUI |
|||
|
|||
public struct SRangeSlider: View { |
|||
/// ` Slider` Binding min & max values |
|||
@Binding var minValue: Float |
|||
@Binding var maxValue: Float |
|||
|
|||
/// Set slider min & max Label values |
|||
let minLabel: String |
|||
let maxLabel: String |
|||
|
|||
/// Set slider width |
|||
let sliderWidth: Float |
|||
|
|||
/// `Slider` background track color |
|||
let backgroundTrackColor: Color |
|||
/// `Slider` selected track color |
|||
let selectedTrackColor: Color |
|||
|
|||
/// Globe background color |
|||
let globeColor: Color |
|||
/// Globe rounded boarder color |
|||
let globeBackgroundColor: Color |
|||
|
|||
/// Slider min & max static and dynamic labels value color |
|||
let sliderMinMaxValuesColor: Color |
|||
|
|||
/// `Slider` init |
|||
public init(minValue: Binding<Float>, |
|||
maxValue: Binding<Float>, |
|||
minLabel: String = "0", |
|||
maxLabel: String = "100", |
|||
sliderWidth: Float = 0, |
|||
backgroundTrackColor: Color = Color(UIColor.systemTeal).opacity(0.3), |
|||
selectedTrackColor: Color = Color.blue.opacity(25), |
|||
globeColor: Color = Color.orange, |
|||
globeBackgroundColor: Color = Color.black, |
|||
sliderMinMaxValuesColor: Color = Color.black) { |
|||
self._minValue = minValue |
|||
self._maxValue = maxValue |
|||
self.minLabel = minLabel |
|||
self.maxLabel = maxLabel |
|||
self.sliderWidth = sliderWidth |
|||
self.backgroundTrackColor = backgroundTrackColor |
|||
self.selectedTrackColor = selectedTrackColor |
|||
self.globeColor = globeColor |
|||
self.globeBackgroundColor = globeBackgroundColor |
|||
self.sliderMinMaxValuesColor = sliderMinMaxValuesColor |
|||
} |
|||
|
|||
/// `Slider` view setup |
|||
public var body: some View { |
|||
|
|||
VStack { |
|||
|
|||
/// `Slider` start & end static values show in view |
|||
HStack { |
|||
// start value |
|||
Text(minLabel) |
|||
.offset(x: 28, y: 20) |
|||
.frame(width: 30, height: 30, alignment: .leading) |
|||
.foregroundColor(sliderMinMaxValuesColor) |
|||
|
|||
Spacer() |
|||
// end value |
|||
Text(maxLabel) |
|||
.offset(x: -18, y: 20) |
|||
.frame(width: 30, height: 30, alignment: .trailing) |
|||
.foregroundColor(sliderMinMaxValuesColor) |
|||
} |
|||
|
|||
/// `Slider` track view with glob view |
|||
ZStack (alignment: Alignment(horizontal: .leading, vertical: .center), content: { |
|||
// background track view |
|||
Capsule() |
|||
.fill(backgroundTrackColor) |
|||
.frame(width: CGFloat(self.sliderWidth + 10), height: 30) |
|||
|
|||
// selected track view |
|||
Capsule() |
|||
.fill(selectedTrackColor) |
|||
.offset(x: CGFloat(self.minValue)) |
|||
.frame(width: CGFloat((self.maxValue) - self.minValue), height: 30) |
|||
|
|||
// minimum value glob view |
|||
Circle() |
|||
.fill(globeColor) |
|||
.frame(width: 30, height: 30) |
|||
.background(Circle().stroke(globeBackgroundColor, lineWidth: 2)) |
|||
.offset(x: CGFloat(self.minValue)) |
|||
.gesture(DragGesture().onChanged({ (value) in |
|||
/// drag validation |
|||
if value.location.x > 8 && Float(value.location.x) <= self.sliderWidth && |
|||
value.location.x < CGFloat(self.maxValue - 30) { |
|||
// set min value of slider |
|||
self.minValue = Float(value.location.x - 8) |
|||
} |
|||
})) |
|||
|
|||
// minimum value text draw inside minimum glob view |
|||
Text(String(format: "%.0f", (self.minValue / self.sliderWidth) * 100)) |
|||
.offset(x: CGFloat(self.minValue)) |
|||
.frame(width: 30, height: 30, alignment: .center) |
|||
.foregroundColor(sliderMinMaxValuesColor) |
|||
|
|||
// maximum value glob view |
|||
Circle() |
|||
.fill(globeColor) |
|||
.frame(width: 30, height: 30) |
|||
.background(Circle().stroke(globeBackgroundColor, lineWidth: 2)) |
|||
.offset(x: CGFloat(self.maxValue - 18)) |
|||
.gesture(DragGesture().onChanged({ (value) in |
|||
/// drag validation |
|||
if Float(value.location.x - 8) <= self.sliderWidth && value.location.x > CGFloat(self.minValue + 50) { |
|||
// set max value of slider |
|||
self.maxValue = Float(value.location.x - 8) |
|||
} |
|||
})) |
|||
|
|||
// maximum value text draw inside maximum glob view |
|||
Text(String(format: "%.0f", (self.maxValue / self.sliderWidth) * 100)) |
|||
.offset(x: CGFloat(self.maxValue - 18)) |
|||
.frame(width: 30, height: 30, alignment: .center) |
|||
.foregroundColor(sliderMinMaxValuesColor) |
|||
}) |
|||
.padding() |
|||
} |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue