feat: Update video element styles for improved layout and accessibility; enhance build script for device installation and launching

This commit is contained in:
Faded
2026-03-07 11:11:16 +05:00
parent c4a9cc9335
commit 007b5f7bea
3 changed files with 86 additions and 83 deletions

View File

@@ -1975,7 +1975,7 @@ video {
overflow: hidden;
cursor: pointer;
position: relative;
min-height: 38px;
min-height: 48px;
transition: border-color 200ms ease;
}
@@ -1987,6 +1987,9 @@ video {
position: relative;
padding: 10px 12px;
overflow: hidden;
display: flex;
align-items: center;
gap: 10px;
}
/* Background Fill - Yellow when ON */
@@ -2016,15 +2019,15 @@ video {
gap: 10px;
}
/* Icon Container */
/* Icon Container proportional to card height */
.torch-icon-fa {
width: 20px;
height: 20px;
font-size: 20px;
width: 24px;
height: 24px;
font-size: 24px;
flex-shrink: 0;
color: #8b949e;
transition: color 300ms ease;
line-height: 20px;
line-height: 24px;
text-align: center;
}
@@ -2033,12 +2036,13 @@ video {
text-shadow: 0 0 8px rgba(255, 215, 0, 0.8), 0 0 4px rgba(255, 215, 0, 0.6);
}
/* Text Container */
/* Text Container ensure text doesn't wrap */
.torch-text {
display: flex;
flex-direction: column;
gap: 2px;
flex: 1;
min-width: 0;
}
.torch-label {
@@ -2365,26 +2369,40 @@ video {
padding: 10px 12px;
}
/* Exposure compact card (2-row: icon+label top, buttons bottom) */
/* Exposure compact card - match other cards (horizontal layout) */
.exposure-card {
flex-direction: column;
align-items: flex-start;
gap: 5px;
cursor: default;
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
min-height: 48px;
}
.exp-top-row {
display: flex;
align-items: center;
gap: 8px;
gap: 10px;
flex: 1;
min-width: 0;
}
/* Align +/- buttons under the text (icon 18px + gap 8px = 26px indent) */
/* Buttons should be aligned right, match torch-value spacing */
.exp-btn-row {
display: flex;
align-items: center;
gap: 5px;
padding-left: 26px;
flex-shrink: 0;
}
.exposure-icon-fa {
width: 24px;
height: 24px;
font-size: 24px;
flex-shrink: 0;
color: #8b949e;
transition: color 200ms ease;
line-height: 24px;
text-align: center;
}
.exposure-label-group {
@@ -2647,42 +2665,45 @@ input[type="range"].zoom-slider {
padding: 0;
}
/* M3 thumb 20dp circle, elevation shadow, no border */
/* M3 thumb 16dp bar/pill (Material 3 label slider style), elevation shadow, no border */
input[type="range"].zoom-slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
width: 4px;
height: 16px;
border-radius: 2px;
background: #ef5350;
cursor: pointer;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.55), 0 1px 2px rgba(0, 0, 0, 0.35);
transition: box-shadow 200ms cubic-bezier(0.2, 0, 0, 1);
}
/* M3 hover state layer */
/* M3 hover state layer (bar style) */
input[type="range"].zoom-slider:hover::-webkit-slider-thumb {
box-shadow: 0 0 0 8px rgba(239, 83, 80, 0.12),
width: 6px;
box-shadow: 0 0 0 6px rgba(239, 83, 80, 0.12),
0 1px 3px rgba(0, 0, 0, 0.55);
}
/* M3 focus state layer */
/* M3 focus state layer (bar style) */
input[type="range"].zoom-slider:focus::-webkit-slider-thumb {
box-shadow: 0 0 0 10px rgba(239, 83, 80, 0.14),
width: 6px;
box-shadow: 0 0 0 8px rgba(239, 83, 80, 0.14),
0 1px 3px rgba(0, 0, 0, 0.55);
}
/* M3 pressed state layer */
/* M3 pressed state layer (bar style) */
input[type="range"].zoom-slider:active::-webkit-slider-thumb {
box-shadow: 0 0 0 12px rgba(239, 83, 80, 0.18),
width: 6px;
box-shadow: 0 0 0 10px rgba(239, 83, 80, 0.18),
0 1px 3px rgba(0, 0, 0, 0.55);
}
/* Firefox */
/* Firefox M3 bar style */
input[type="range"].zoom-slider::-moz-range-thumb {
width: 20px;
height: 20px;
border-radius: 50%;
width: 4px;
height: 16px;
border-radius: 2px;
background: #ef5350;
cursor: pointer;
border: none;
@@ -2725,6 +2746,13 @@ input[type="range"].zoom-slider::-moz-range-progress {
.zoom-reset-btn:active {
transform: scale(0.90);
}
.zoom-reset-btn:disabled {
opacity: 0.4;
cursor: not-allowed;
color: #443d3d;
border-color: transparent;
background: #0d1117;
}
/* -------- NETWORK CARD -------- */

View File

@@ -455,7 +455,7 @@
onchange="onZoomSliderCommit(this.value)">
</div>
<button class="zoom-reset-btn" onclick="resetZoom()" title="Reset zoom">
<i class="fas fa-compress-alt"></i>
<i class="fas fa-undo"></i>
</button>
</div>
@@ -2297,6 +2297,9 @@
if (el) el.textContent = v.toFixed(1) + '×';
// Pan container visible only when zoom > 1
document.getElementById('panContainer')?.classList.toggle('visible', v > 1.0);
// Reset button only enabled when zoom !== 1.0
const resetBtn = document.querySelector('.zoom-reset-btn');
if (resetBtn) resetBtn.disabled = (Math.abs(v - 1.0) < 0.01); // Account for float precision
// Update filled-track CSS variable
const slider = document.getElementById('zoomSlider');
if (slider) {
@@ -2417,7 +2420,7 @@
const el = document.getElementById('exposureValue');
// Show target value as visual feedback (like torch shows intended state)
if (el) el.textContent = (targetEv > 0 ? '+' : '') + targetEv;
executingState.start('exposureCompensation', targetEv, '.exposure-card');
executingState.start('exposureCompensation', targetEv, '#exposureCard');
try {
await dashboardViewModel.setExposure(targetEv);
_currentEv = targetEv; // Mark confirmed locally too

View File

@@ -258,83 +258,55 @@ execute_build() {
print_status "💾" "Size: ${BRIGHT_RED}${APK_SIZE}${RESET}"
echo ""
# Install if requested using Gradle (handles all connected devices automatically)
# Install if requested using Gradle (professional Android approach)
if [ "$INSTALL" = "true" ]; then
# Get list of connected devices and show all with model/version
local DEVICES=()
while read -r line; do
# Parse device ID and status from adb devices output
local device_id=$(echo "$line" | awk '{print $1}')
local device_status=$(echo "$line" | awk '{print $2}')
if [ "$device_status" = "device" ] && [ -n "$device_id" ]; then
DEVICES+=("$device_id")
fi
done < <(adb devices | tail -n +2)
local DEVICE_COUNT=${#DEVICES[@]}
# Capitalize first letter of BUILD_TYPE for Gradle task (e.g., debug -> Debug)
local BUILD_TYPE_UPPER=$(echo "$BUILD_TYPE" | tr '[:lower:]' '[:upper:]' | cut -c1)$(echo "$BUILD_TYPE" | cut -c2-)
# Show device info using standard adb approach
local DEVICE_COUNT=$(adb devices | grep -E '^[a-zA-Z0-9].*[[:space:]]device$' | wc -l)
if [ $DEVICE_COUNT -eq 0 ]; then
print_status "⚠️" "No connected devices found"
echo ""
return 0
fi
print_status "📱" "Connected Devices: ${BRIGHT_RED}${DEVICE_COUNT}${RESET}"
for ((i=0; i<DEVICE_COUNT; i++)); do
local device="${DEVICES[$i]}"
local DEVICE_MODEL=$(adb -s "$device" shell getprop ro.product.model 2>/dev/null | tr -d '\r' | xargs || echo "Unknown")
local DEVICE_VERSION=$(adb -s "$device" shell getprop ro.build.version.release 2>/dev/null | tr -d '\r' | xargs || echo "?")
printf " ${BRIGHT_RED}[%d/%d]${RESET} ${GRAY}%s${RESET} - ${WHITE}%s (Android %s)${RESET}\n" $((i+1)) $DEVICE_COUNT "$device" "$DEVICE_MODEL" "$DEVICE_VERSION"
adb devices | grep -E '^[a-zA-Z0-9].*[[:space:]]device$' | while read -r device _; do
local DEVICE_MODEL=$(adb -s "$device" shell getprop ro.product.model 2>/dev/null || echo "Unknown")
local DEVICE_VERSION=$(adb -s "$device" shell getprop ro.build.version.release 2>/dev/null || echo "?")
echo -e " ${BRIGHT_RED}[${device:0:16}]${RESET} ${WHITE}${DEVICE_MODEL}${RESET} - ${GRAY}Android ${DEVICE_VERSION}${RESET}"
done
echo ""
print_status "📥" "Installing to all connected devices..."
echo ""
# Capitalize first letter of BUILD_TYPE for Gradle task (e.g., debug -> Debug)
local BUILD_TYPE_UPPER=$(echo "$BUILD_TYPE" | tr '[:lower:]' '[:upper:]' | cut -c1)$(echo "$BUILD_TYPE" | cut -c2-)
# Use gradle's standard install task (Android official way)
local INSTALL_TASK="app:installDefault${BUILD_TYPE_UPPER}"
local INSTALL_LOG=$(mktemp)
if ./gradlew "$INSTALL_TASK" --no-daemon --quiet > "$INSTALL_LOG" 2>&1; then
if ./gradlew "$INSTALL_TASK" --no-daemon 2>&1 | tail -3; then
print_status "✅" "Installation successful on ${BRIGHT_RED}${DEVICE_COUNT}${RESET} device(s)"
# Launch using Android's official am start command (not gradle run which doesn't exist)
echo ""
print_status "🚀" "Launching app on all devices..."
local LAUNCH_SUCCESS=0
# Determine package name based on build type
local PACKAGE_NAME="com.fadcam.beta"
if [ "$BUILD_TYPE" = "release" ]; then
PACKAGE_NAME="com.fadcam"
fi
for ((i=0; i<DEVICE_COUNT; i++)); do
local device="${DEVICES[$i]}"
local DEVICE_MODEL=$(adb -s "$device" shell getprop ro.product.model 2>/dev/null | tr -d '\r' | xargs || echo "Unknown")
if adb -s "$device" shell am start -n "${PACKAGE_NAME}/com.fadcam.SplashActivity" >/dev/null 2>&1; then
echo -e " ${BRIGHT_RED}[${device}]${RESET} ${WHITE}${DEVICE_MODEL}${RESET} - ✅ Launched"
((LAUNCH_SUCCESS++))
[ "$BUILD_TYPE" = "release" ] && PACKAGE_NAME="com.fadcam"
# Use am start with proper activity path - this is the Android standard
adb devices | grep -E '^[a-zA-Z0-9].*[[:space:]]device$' | while read -r device _; do
# Launch the app (Android's official way) - note: full class path needed
if adb -s "$device" shell am start -W -n "${PACKAGE_NAME}/com.fadcam.SplashActivity" 2>/dev/null; then
echo -e " ${BRIGHT_RED}[${device:0:16}]${RESET} ✅ Launched successfully"
else
echo -e " ${BRIGHT_RED}[${device}]${RESET} ${WHITE}${DEVICE_MODEL}${RESET} - ❌ Failed to launch"
echo -e " ${BRIGHT_RED}[${device:0:16}]${RESET} ⚠️ Launch may have failed"
fi
done
if [ $LAUNCH_SUCCESS -gt 0 ]; then
print_status "✅" "App launched on ${BRIGHT_RED}${LAUNCH_SUCCESS}/${DEVICE_COUNT}${RESET} device(s)"
else
print_status "⚠️" "Could not launch app on any device"
fi
else
print_status "❌" "Installation failed"
echo ""
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
echo -e "${BRIGHT_RED}Installation Error:${RESET}"
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
cat "$INSTALL_LOG"
echo -e "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"
rm -f "$INSTALL_LOG"
echo ""
return 1
fi
rm -f "$INSTALL_LOG"
else
print_status "💡" "APK ready: ${BRIGHT_RED}${APK_PATH}${RESET}"
fi