Compare commits
1 Commits
develop
...
feature/ch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ba9a750ea |
@@ -1,5 +1,6 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useRef } from "react";
|
||||||
import {
|
import {
|
||||||
|
Alert,
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
@@ -11,6 +12,7 @@ import {
|
|||||||
import { Switch } from "@rneui/themed";
|
import { Switch } from "@rneui/themed";
|
||||||
import { useNavigation } from "@react-navigation/native";
|
import { useNavigation } from "@react-navigation/native";
|
||||||
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
||||||
|
import Swipeable from "react-native-gesture-handler/Swipeable";
|
||||||
import { SheetHeaderItem } from "@/components/atom/SheetHeaderItem";
|
import { SheetHeaderItem } from "@/components/atom/SheetHeaderItem";
|
||||||
import { AS } from "../../storageControl";
|
import { AS } from "../../storageControl";
|
||||||
import { STORAGE_KEYS } from "@/constants";
|
import { STORAGE_KEYS } from "@/constants";
|
||||||
@@ -302,6 +304,7 @@ export const DataSourceSettings = () => {
|
|||||||
useState<JrDataSystemUiVariant>(
|
useState<JrDataSystemUiVariant>(
|
||||||
getJrDataSystemUiVariant(DEFAULT_JR_DATA_SYSTEM_ENV),
|
getJrDataSystemUiVariant(DEFAULT_JR_DATA_SYSTEM_ENV),
|
||||||
);
|
);
|
||||||
|
const recordingSwipeRefs = useRef<Record<string, { close: () => void } | null>>({});
|
||||||
|
|
||||||
const applyJrDataSystemEnv = (env: JrDataSystemEnvironmentKey) => {
|
const applyJrDataSystemEnv = (env: JrDataSystemEnvironmentKey) => {
|
||||||
setJrDataSystemEnv(env);
|
setJrDataSystemEnv(env);
|
||||||
@@ -358,6 +361,28 @@ export const DataSourceSettings = () => {
|
|||||||
applyJrDataSystemEnv(env);
|
applyJrDataSystemEnv(env);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const closeRecordingSwipe = (id: string) => {
|
||||||
|
recordingSwipeRefs.current[id]?.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
const confirmDeleteRecording = (id: string, label: string) => {
|
||||||
|
closeRecordingSwipe(id);
|
||||||
|
Alert.alert(
|
||||||
|
"録画を削除",
|
||||||
|
`${label} の録画を削除しますか?`,
|
||||||
|
[
|
||||||
|
{ text: "キャンセル", style: "cancel" },
|
||||||
|
{
|
||||||
|
text: "削除",
|
||||||
|
style: "destructive",
|
||||||
|
onPress: () => {
|
||||||
|
void deleteRecording(id);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[styles.container, { backgroundColor: fixed.primary }]}>
|
<View style={[styles.container, { backgroundColor: fixed.primary }]}>
|
||||||
<SheetHeaderItem
|
<SheetHeaderItem
|
||||||
@@ -553,13 +578,16 @@ export const DataSourceSettings = () => {
|
|||||||
month: 'numeric', day: 'numeric',
|
month: 'numeric', day: 'numeric',
|
||||||
hour: '2-digit', minute: '2-digit',
|
hour: '2-digit', minute: '2-digit',
|
||||||
});
|
});
|
||||||
return (
|
const recordingRow = (
|
||||||
<View
|
<TouchableOpacity
|
||||||
key={rec.id}
|
onPress={() => startPlayback(rec.id)}
|
||||||
|
disabled={isPlaying}
|
||||||
|
activeOpacity={0.72}
|
||||||
style={{
|
style={{
|
||||||
flexDirection: 'row', alignItems: 'center',
|
flexDirection: 'row', alignItems: 'center',
|
||||||
backgroundColor: colors.backgroundSecondary,
|
backgroundColor: colors.backgroundSecondary,
|
||||||
borderRadius: 8, padding: 10, gap: 8,
|
borderRadius: 8, padding: 12, gap: 10,
|
||||||
|
opacity: isPlaying ? 0.6 : 1,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<View style={{ flex: 1 }}>
|
<View style={{ flex: 1 }}>
|
||||||
@@ -570,29 +598,71 @@ export const DataSourceSettings = () => {
|
|||||||
{rec.snapshotCount} コマ / {durationLabel}
|
{rec.snapshotCount} コマ / {durationLabel}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
{!isPlaying && (
|
<View style={{ alignItems: 'flex-end', gap: 4 }}>
|
||||||
<TouchableOpacity
|
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 4 }}>
|
||||||
onPress={() => startPlayback(rec.id)}
|
<MaterialCommunityIcons
|
||||||
|
name={isPlaying ? 'pause-circle-outline' : 'play-circle-outline'}
|
||||||
|
size={18}
|
||||||
|
color={isPlaying ? colors.textTertiary : '#43a047'}
|
||||||
|
/>
|
||||||
|
<Text
|
||||||
|
style={{
|
||||||
|
color: isPlaying ? colors.textTertiary : colors.textPrimary,
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: '600',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{isPlaying ? '再生中は操作不可' : 'タップで再生'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
{!isPlaying && (
|
||||||
|
<Text style={{ color: colors.textTertiary, fontSize: 10 }}>
|
||||||
|
左へスワイプで削除
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
<MaterialCommunityIcons
|
||||||
|
name="chevron-right"
|
||||||
|
size={18}
|
||||||
|
color={colors.iconSecondary}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isPlaying) {
|
||||||
|
return <View key={rec.id}>{recordingRow}</View>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Swipeable
|
||||||
|
key={rec.id}
|
||||||
|
ref={(instance) => {
|
||||||
|
recordingSwipeRefs.current[rec.id] = instance;
|
||||||
|
}}
|
||||||
|
friction={2}
|
||||||
|
overshootRight={false}
|
||||||
|
rightThreshold={48}
|
||||||
|
renderRightActions={() => (
|
||||||
|
<View
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: '#43a047', borderRadius: 6,
|
width: 96,
|
||||||
paddingHorizontal: 10, paddingVertical: 6,
|
borderRadius: 8,
|
||||||
|
backgroundColor: '#e53935',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
marginLeft: 6,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text style={{ color: '#fff', fontWeight: 'bold', fontSize: 12 }}>▶</Text>
|
<MaterialCommunityIcons name="trash-can-outline" size={18} color="#fff" />
|
||||||
</TouchableOpacity>
|
<Text style={{ color: '#fff', fontSize: 11, fontWeight: 'bold', marginTop: 4 }}>
|
||||||
|
削除
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
)}
|
)}
|
||||||
{!isPlaying && (
|
onSwipeableOpen={() => confirmDeleteRecording(rec.id, dateLabel)}
|
||||||
<TouchableOpacity
|
>
|
||||||
onPress={() => deleteRecording(rec.id)}
|
{recordingRow}
|
||||||
style={{
|
</Swipeable>
|
||||||
borderColor: '#e53935', borderWidth: 1, borderRadius: 6,
|
|
||||||
paddingHorizontal: 10, paddingVertical: 6,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text style={{ color: '#e53935', fontSize: 12 }}>削除</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
Reference in New Issue
Block a user