@umituz/react-native-design-system 4.23.97 → 4.23.101

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.
Files changed (77) hide show
  1. package/package.json +1 -1
  2. package/src/atoms/AtomicInput.tsx +0 -2
  3. package/src/atoms/button/AtomicButton.tsx +7 -0
  4. package/src/atoms/button/types/index.ts +4 -0
  5. package/src/atoms/input/hooks/useInputState.ts +3 -7
  6. package/src/haptics/infrastructure/services/HapticService.ts +1 -1
  7. package/src/media/domain/entities/{MultimediaFlashcardTypes.ts → MediaAttachments.ts} +13 -32
  8. package/src/media/index.ts +24 -23
  9. package/src/media/{presentation/hooks/useCardMediaGeneration.ts → infrastructure/hooks/useGenericMediaGeneration.ts} +77 -31
  10. package/src/media/infrastructure/services/MediaGenerationService.ts +1 -1
  11. package/src/media/infrastructure/services/MediaOptimizerService.ts +1 -1
  12. package/src/media/infrastructure/services/MediaUploadService.ts +1 -1
  13. package/src/media/infrastructure/services/MediaValidationService.ts +1 -1
  14. package/src/media/infrastructure/services/MultimediaFlashcardService.ts +1 -1
  15. package/src/media/infrastructure/utils/PermissionManager.ts +1 -1
  16. package/src/media/infrastructure/utils/media-collection-utils.ts +4 -2
  17. package/src/media/infrastructure/utils/mediaPickerMappers.ts +1 -1
  18. package/src/media/presentation/hooks/multimedia.types.ts +1 -1
  19. package/src/media/presentation/hooks/useCardMultimediaFlashcard.ts +4 -4
  20. package/src/media/presentation/hooks/useMedia.ts +2 -2
  21. package/src/media/presentation/hooks/useMediaGeneration.ts +5 -88
  22. package/src/media/presentation/hooks/useMediaUpload.ts +1 -1
  23. package/src/media/presentation/hooks/useMediaValidation.ts +1 -1
  24. package/src/media/presentation/hooks/useMultimediaFlashcard.ts +1 -1
  25. package/src/molecules/navigation/components/NavigationHeader.tsx +3 -3
  26. package/src/molecules/navigation/utils/AppNavigation.ts +3 -3
  27. package/src/offline/index.ts +1 -0
  28. package/src/offline/infrastructure/storage/OfflineConfigStore.ts +34 -0
  29. package/src/offline/presentation/hooks/useOffline.ts +8 -4
  30. package/src/storage/domain/utils/devUtils.ts +0 -24
  31. package/src/storage/index.ts +1 -1
  32. package/src/storage/infrastructure/adapters/StorageService.ts +5 -10
  33. package/src/storage/infrastructure/repositories/BaseStorageOperations.ts +5 -8
  34. package/src/storage/presentation/hooks/CacheStorageOperations.ts +5 -11
  35. package/src/storage/presentation/hooks/useStore.ts +13 -5
  36. package/src/utilities/sharing/presentation/hooks/useSharing.ts +3 -3
  37. package/src/layouts/ScreenLayout/ScreenLayout.example.tsx +0 -92
  38. package/src/media/domain/entities/CardMultimedia.types.README.md +0 -129
  39. package/src/media/domain/entities/CardMultimedia.types.ts +0 -120
  40. package/src/media/domain/entities/Media.README.md +0 -80
  41. package/src/media/domain/entities/MultimediaFlashcardTypes.README.md +0 -144
  42. package/src/media/domain/utils/MediaUtils.README.md +0 -178
  43. package/src/media/index.ts.README.md +0 -191
  44. package/src/media/infrastructure/services/CardMediaGenerationService.README.md +0 -99
  45. package/src/media/infrastructure/services/CardMediaGenerationService.ts +0 -101
  46. package/src/media/infrastructure/services/CardMediaOptimizerService.README.md +0 -167
  47. package/src/media/infrastructure/services/CardMediaOptimizerService.ts +0 -36
  48. package/src/media/infrastructure/services/CardMediaUploadService.README.md +0 -123
  49. package/src/media/infrastructure/services/CardMediaUploadService.ts +0 -62
  50. package/src/media/infrastructure/services/CardMediaValidationService.README.md +0 -134
  51. package/src/media/infrastructure/services/CardMediaValidationService.ts +0 -81
  52. package/src/media/infrastructure/services/CardMultimediaService.README.md +0 -176
  53. package/src/media/infrastructure/services/CardMultimediaService.ts +0 -98
  54. package/src/media/infrastructure/services/MediaGenerationService.README.md +0 -142
  55. package/src/media/infrastructure/services/MediaOptimizerService.README.md +0 -145
  56. package/src/media/infrastructure/services/MediaPickerService.README.md +0 -106
  57. package/src/media/infrastructure/services/MediaSaveService.README.md +0 -120
  58. package/src/media/infrastructure/services/MediaUploadService.README.md +0 -135
  59. package/src/media/infrastructure/services/MediaValidationService.README.md +0 -135
  60. package/src/media/infrastructure/services/MultimediaFlashcardService.README.md +0 -142
  61. package/src/media/infrastructure/utils/mediaHelpers.README.md +0 -96
  62. package/src/media/infrastructure/utils/mediaPickerMappers.README.md +0 -129
  63. package/src/media/presentation/hooks/card-multimedia.types.README.md +0 -177
  64. package/src/media/presentation/hooks/card-multimedia.types.ts +0 -53
  65. package/src/media/presentation/hooks/multimedia.types.README.md +0 -201
  66. package/src/media/presentation/hooks/useCardMediaGeneration.README.md +0 -164
  67. package/src/media/presentation/hooks/useCardMediaUpload.README.md +0 -153
  68. package/src/media/presentation/hooks/useCardMediaUpload.ts +0 -84
  69. package/src/media/presentation/hooks/useCardMediaValidation.README.md +0 -176
  70. package/src/media/presentation/hooks/useCardMediaValidation.ts +0 -101
  71. package/src/media/presentation/hooks/useCardMultimediaFlashcard.README.md +0 -158
  72. package/src/media/presentation/hooks/useMedia.README.md +0 -94
  73. package/src/media/presentation/hooks/useMediaGeneration.README.md +0 -118
  74. package/src/media/presentation/hooks/useMediaUpload.README.md +0 -108
  75. package/src/media/presentation/hooks/useMediaValidation.README.md +0 -134
  76. package/src/media/presentation/hooks/useMultimediaFlashcard.README.md +0 -141
  77. package/src/storage/domain/utils/__tests__/devUtils.test.ts +0 -97
@@ -6,7 +6,7 @@
6
6
  import { useState, useCallback } from "react";
7
7
  import { formatFileSize } from "../../infrastructure/utils/media-collection-utils";
8
8
  import type { UseMediaValidationResult } from "./multimedia.types";
9
- import type { MediaValidation, MediaFile } from "../../domain/entities/MultimediaFlashcardTypes";
9
+ import type { MediaValidation, MediaFile } from "../../domain/entities/MediaAttachments";
10
10
 
11
11
  export const useMediaValidation = (): UseMediaValidationResult => {
12
12
  const [isValidating, setIsValidating] = useState(false);
@@ -10,7 +10,7 @@ import type {
10
10
  MediaAttachment,
11
11
  MultimediaFlashcard,
12
12
  CreateMultimediaCardData,
13
- } from "../../domain/entities/MultimediaFlashcardTypes";
13
+ } from "../../domain/entities/MediaAttachments";
14
14
 
15
15
  // Export individual hooks
16
16
  export { useMediaUpload } from "./useMediaUpload";
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React, { useMemo } from 'react';
2
2
  import { View, StyleSheet, TouchableOpacity } from 'react-native';
3
3
  import { AtomicText } from '../../../atoms';
4
4
  import { AtomicIcon, useIconName } from '../../../atoms';
@@ -20,7 +20,7 @@ export const NavigationHeader: React.FC<NavigationHeaderProps> = ({
20
20
  const insets = useSafeAreaInsets();
21
21
  const arrowLeftIcon = useIconName('arrowLeft');
22
22
 
23
- const styles = StyleSheet.create({
23
+ const styles = useMemo(() => StyleSheet.create({
24
24
  container: {
25
25
  paddingTop: insets.top,
26
26
  paddingHorizontal: tokens.spacing.md,
@@ -45,7 +45,7 @@ export const NavigationHeader: React.FC<NavigationHeaderProps> = ({
45
45
  flex: 1,
46
46
  textAlign: 'left',
47
47
  },
48
- });
48
+ }), [tokens, insets]);
49
49
 
50
50
  return (
51
51
  <View style={styles.container}>
@@ -40,7 +40,7 @@ export const navigate = (name: string, params?: object): void => {
40
40
  if (__DEV__) {
41
41
  }
42
42
  if (navigationRef?.isReady()) {
43
- navigationRef.navigate(name as never, params as never);
43
+ navigationRef.navigate(name, params);
44
44
  }
45
45
  };
46
46
 
@@ -54,10 +54,10 @@ export const navigateNested = (navigatorName: string, screenName: string, params
54
54
  if (__DEV__) {
55
55
  }
56
56
  if (navigationRef?.isReady()) {
57
- navigationRef.navigate(navigatorName as never, {
57
+ navigationRef.navigate(navigatorName, {
58
58
  screen: screenName,
59
59
  params,
60
- } as never);
60
+ });
61
61
  }
62
62
  };
63
63
 
@@ -14,6 +14,7 @@ export type {
14
14
 
15
15
  // Store
16
16
  export { useOfflineStore } from './infrastructure/storage/OfflineStore';
17
+ export { useOfflineConfigStore } from './infrastructure/storage/OfflineConfigStore';
17
18
 
18
19
  // Hooks
19
20
  export { useOffline, configureOffline } from './presentation/hooks/useOffline';
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Offline Config Store
3
+ * Centralized configuration for offline functionality
4
+ * Replaces module-level mutable state with Zustand store
5
+ */
6
+
7
+ import { create } from 'zustand';
8
+ import type { OfflineConfig } from '../../types';
9
+
10
+ interface OfflineConfigStore {
11
+ config: OfflineConfig;
12
+ setConfig: (config: OfflineConfig) => void;
13
+ mergeConfig: (partialConfig: OfflineConfig) => void;
14
+ reset: () => void;
15
+ }
16
+
17
+ export const useOfflineConfigStore = create<OfflineConfigStore>((set) => ({
18
+ config: {},
19
+
20
+ setConfig: (config) => set({ config }),
21
+
22
+ mergeConfig: (partialConfig) => set((state) => ({
23
+ config: { ...state.config, ...partialConfig }
24
+ })),
25
+
26
+ reset: () => set({ config: {} }),
27
+ }));
28
+
29
+ /**
30
+ * Get current config (for non-React contexts)
31
+ */
32
+ export const getOfflineConfig = (): OfflineConfig => {
33
+ return useOfflineConfigStore.getState().config;
34
+ };
@@ -10,6 +10,7 @@ import type { NetworkState as ExpoNetworkState } from 'expo-network';
10
10
  import type { NetworkState, OfflineConfig } from '../../types';
11
11
  import { useOfflineStore } from '../../infrastructure/storage/OfflineStore';
12
12
  import { networkEvents } from '../../infrastructure/events/NetworkEvents';
13
+ import { useOfflineConfigStore } from '../../infrastructure/storage/OfflineConfigStore';
13
14
 
14
15
  /**
15
16
  * Convert expo-network state to our internal format
@@ -21,14 +22,17 @@ const toNetworkState = (state: ExpoNetworkState): NetworkState => ({
21
22
  details: null,
22
23
  });
23
24
 
24
- let globalConfig: OfflineConfig = {};
25
-
25
+ /**
26
+ * Configure offline settings globally
27
+ * This is a facade over the config store for backward compatibility
28
+ */
26
29
  export const configureOffline = (config: OfflineConfig): void => {
27
- globalConfig = config;
30
+ useOfflineConfigStore.getState().setConfig(config);
28
31
  };
29
32
 
30
33
  export const useOffline = (config?: OfflineConfig) => {
31
34
  const store = useOfflineStore();
35
+ const globalConfig = useOfflineConfigStore((state) => state.config);
32
36
  const isInitialized = useRef(false);
33
37
  const previousStateRef = useRef<NetworkState | null>(null);
34
38
  const isMountedRef = useRef(true);
@@ -36,7 +40,7 @@ export const useOffline = (config?: OfflineConfig) => {
36
40
  // Memoize merged config to prevent unnecessary effect re-runs
37
41
  const mergedConfig = useMemo(
38
42
  () => ({ ...globalConfig, ...config }),
39
- [config]
43
+ [globalConfig, config]
40
44
  );
41
45
 
42
46
  const handleNetworkStateChange = useCallback((state: ExpoNetworkState) => {
@@ -9,27 +9,3 @@ export const isDev = (): boolean => {
9
9
  return __DEV__;
10
10
  };
11
11
 
12
- /**
13
- * Log warning in development mode only
14
- * All logs are disabled
15
- */
16
- export const devWarn = (_message: string, ..._args: unknown[]): void => {
17
- // Disabled
18
- };
19
-
20
- /**
21
- * Log error in development mode only
22
- * All logs are disabled
23
- */
24
- export const devError = (_message: string, ..._args: unknown[]): void => {
25
- // Disabled
26
- };
27
-
28
- /**
29
- * Log info in development mode only
30
- * All logs are disabled
31
- */
32
- export const devLog = (_message: string, ..._args: unknown[]): void => {
33
- // Disabled
34
- };
35
-
@@ -82,7 +82,7 @@ export { TIME_MS, DEFAULT_TTL, CACHE_VERSION } from './domain/constants/CacheDef
82
82
  // DOMAIN LAYER - Development Utilities
83
83
  // =============================================================================
84
84
 
85
- export { isDev, devWarn, devError, devLog } from './domain/utils/devUtils';
85
+ export { isDev } from './domain/utils/devUtils';
86
86
 
87
87
  // =============================================================================
88
88
  // DOMAIN LAYER - Store Types
@@ -6,7 +6,6 @@
6
6
  */
7
7
 
8
8
  import AsyncStorage from '@react-native-async-storage/async-storage';
9
- import { devWarn } from '../../domain/utils/devUtils';
10
9
  import type { StateStorage } from '../../domain/types/Store';
11
10
 
12
11
  /**
@@ -17,9 +16,7 @@ export const storageService: StateStorage = {
17
16
  getItem: async (name: string): Promise<string | null> => {
18
17
  try {
19
18
  return await AsyncStorage.getItem(name);
20
- } catch (error) {
21
- const errorMessage = `StorageService: Failed to get item "${name}"`;
22
- devWarn(errorMessage, error);
19
+ } catch (_error) {
23
20
  return null;
24
21
  }
25
22
  },
@@ -27,18 +24,16 @@ export const storageService: StateStorage = {
27
24
  setItem: async (name: string, value: string): Promise<void> => {
28
25
  try {
29
26
  await AsyncStorage.setItem(name, value);
30
- } catch (error) {
31
- const errorMessage = `StorageService: Failed to set item "${name}"`;
32
- devWarn(errorMessage, error);
27
+ } catch (_error) {
28
+ // Silent failure
33
29
  }
34
30
  },
35
31
 
36
32
  removeItem: async (name: string): Promise<void> => {
37
33
  try {
38
34
  await AsyncStorage.removeItem(name);
39
- } catch (error) {
40
- const errorMessage = `StorageService: Failed to remove item "${name}"`;
41
- devWarn(errorMessage, error);
35
+ } catch (_error) {
36
+ // Silent failure
42
37
  }
43
38
  },
44
39
  };
@@ -14,7 +14,6 @@ import {
14
14
  StorageSerializationError,
15
15
  StorageDeserializationError,
16
16
  } from '../../domain/errors/StorageError';
17
- import { devWarn } from '../../domain/utils/devUtils';
18
17
 
19
18
  /**
20
19
  * Base storage operations implementation
@@ -37,7 +36,7 @@ export class BaseStorageOperations {
37
36
  } catch (parseError) {
38
37
  return failure(new StorageDeserializationError(key, parseError), defaultValue);
39
38
  }
40
- } catch (error) {
39
+ } catch (_error) {
41
40
  return failure(new StorageReadError(key, error), defaultValue);
42
41
  }
43
42
  }
@@ -56,7 +55,7 @@ export class BaseStorageOperations {
56
55
 
57
56
  await AsyncStorage.setItem(key, serialized);
58
57
  return success(value);
59
- } catch (error) {
58
+ } catch (_error) {
60
59
  return failure(new StorageWriteError(key, error));
61
60
  }
62
61
  }
@@ -68,7 +67,7 @@ export class BaseStorageOperations {
68
67
  try {
69
68
  await AsyncStorage.removeItem(key);
70
69
  return success(undefined);
71
- } catch (error) {
70
+ } catch (_error) {
72
71
  return failure(new StorageDeleteError(key, error));
73
72
  }
74
73
  }
@@ -80,9 +79,7 @@ export class BaseStorageOperations {
80
79
  try {
81
80
  const value = await AsyncStorage.getItem(key);
82
81
  return value !== null;
83
- } catch (error) {
84
- const errorMessage = `BaseStorageOperations: Failed to check if key "${key}" exists`;
85
- devWarn(errorMessage, error);
82
+ } catch (_error) {
86
83
  return false;
87
84
  }
88
85
  }
@@ -94,7 +91,7 @@ export class BaseStorageOperations {
94
91
  try {
95
92
  await AsyncStorage.clear();
96
93
  return success(undefined);
97
- } catch (error) {
94
+ } catch (_error) {
98
95
  return failure(new StorageDeleteError('ALL_KEYS', error));
99
96
  }
100
97
  }
@@ -7,7 +7,6 @@
7
7
  import { storageRepository } from '../../infrastructure/repositories/AsyncStorageRepository';
8
8
  import type { CachedValue } from '../../domain/entities/CachedValue';
9
9
  import { createCachedValue } from '../../domain/entities/CachedValue';
10
- import { devWarn } from '../../domain/utils/devUtils';
11
10
  import { isValidCachedValue } from '../../domain/utils/ValidationUtils';
12
11
 
13
12
  export interface CacheStorageOptions {
@@ -56,16 +55,11 @@ export class CacheStorageOperations {
56
55
  return parsed as CachedValue<T>;
57
56
  }
58
57
 
59
- if (__DEV__) {
60
- devWarn(`CacheStorageOperations: Invalid cached data structure for key "${key}"`);
61
- }
62
-
63
58
  return null;
64
59
  }
65
60
 
66
61
  return null;
67
- } catch (error) {
68
- devWarn(`CacheStorageOperations: Failed to load cache for key "${key}"`, error);
62
+ } catch (_error) {
69
63
  return null;
70
64
  }
71
65
  }
@@ -85,8 +79,8 @@ export class CacheStorageOperations {
85
79
  try {
86
80
  const cached = createCachedValue(value, ttl || 0, version);
87
81
  await storageRepository.setString(key, JSON.stringify(cached));
88
- } catch (error) {
89
- devWarn(`CacheStorageOperations: Failed to save cache for key "${key}"`, error);
82
+ } catch (_error) {
83
+ // Silent failure
90
84
  }
91
85
  }
92
86
 
@@ -98,8 +92,8 @@ export class CacheStorageOperations {
98
92
 
99
93
  try {
100
94
  await storageRepository.removeItem(key);
101
- } catch (error) {
102
- devWarn(`CacheStorageOperations: Failed to clear cache for key "${key}"`, error);
95
+ } catch (_error) {
96
+ // Silent failure
103
97
  }
104
98
  }
105
99
  }
@@ -3,14 +3,22 @@
3
3
  * Helper for creating stores in components
4
4
  */
5
5
 
6
- import { useMemo, useRef } from 'react';
6
+ import { useMemo } from 'react';
7
7
  import { createStore } from '../../domain/factories/StoreFactory';
8
8
  import type { StoreConfig } from '../../domain/types/Store';
9
9
 
10
10
  export function useStore<T extends object>(config: StoreConfig<T>) {
11
- // Config objesini stabilize et - sadece name değiştiğinde yeni store oluştur
12
- const configRef = useRef(config);
13
- configRef.current = config;
14
- const store = useMemo(() => createStore(configRef.current), [config.name]);
11
+ // Stabilize entire config to track all property changes
12
+ const stableConfig = useMemo(
13
+ () => config,
14
+ [
15
+ config.name,
16
+ config.version,
17
+ config.persist,
18
+ config.storage,
19
+ ]
20
+ );
21
+
22
+ const store = useMemo(() => createStore(stableConfig), [stableConfig]);
15
23
  return store;
16
24
  }
@@ -8,7 +8,7 @@
8
8
  * @layer presentation/hooks
9
9
  */
10
10
 
11
- import { useState, useCallback, useEffect } from 'react';
11
+ import { useState, useCallback, useEffect, useMemo } from 'react';
12
12
  import { SharingService } from '../../infrastructure/services/SharingService';
13
13
  import type { ShareOptions } from '../../domain/entities/Share';
14
14
 
@@ -140,7 +140,7 @@ export const useSharing = () => {
140
140
  []
141
141
  );
142
142
 
143
- return {
143
+ return useMemo(() => ({
144
144
  // Functions
145
145
  share,
146
146
  shareWithAutoType,
@@ -150,5 +150,5 @@ export const useSharing = () => {
150
150
  isAvailable,
151
151
  isSharing,
152
152
  error,
153
- };
153
+ }), [share, shareWithAutoType, shareMultiple, isAvailable, isSharing, error]);
154
154
  };
@@ -1,92 +0,0 @@
1
- /**
2
- * Enhanced ScreenLayout Example
3
- *
4
- * This demonstrates the recommended usage of ScreenLayout with SafeAreaProvider
5
- */
6
-
7
- import React from 'react';
8
- import { View, Text } from 'react-native';
9
- import {
10
- SafeAreaProvider,
11
- ScreenLayout,
12
- ScreenHeader,
13
- AtomicButton,
14
- AtomicText
15
- } from '../../index';
16
-
17
- // 1. Wrap your app root with SafeAreaProvider
18
- export function App() {
19
- return (
20
- <SafeAreaProvider>
21
- <View />
22
- </SafeAreaProvider>
23
- );
24
- }
25
-
26
- // 2. Use ScreenLayout in your screens
27
- export function HomeScreen() {
28
- return (
29
- <ScreenLayout
30
- // Safe area edges - default is ['top']
31
- edges={['top']}
32
- // Enable scrolling - default is true
33
- scrollable={true}
34
- // Optional header
35
- header={
36
- <ScreenHeader
37
- title="Home"
38
- />
39
- }
40
- // Optional footer
41
- footer={
42
- <View style={{ padding: 16 }}>
43
- <AtomicButton onPress={() => console.log('Action')}>
44
- Action Button
45
- </AtomicButton>
46
- </View>
47
- }
48
- >
49
- <AtomicText type="headlineLarge">Welcome to Home</AtomicText>
50
- <AtomicText type="bodyMedium">
51
- This screen uses ScreenLayout with default safe area configuration.
52
- </AtomicText>
53
- </ScreenLayout>
54
- );
55
- }
56
-
57
- // 3. Modal screen example with different safe area edges
58
- export function ModalScreen() {
59
- return (
60
- <ScreenLayout
61
- // Full safe area for modals
62
- edges={['top', 'bottom']}
63
- scrollable={false}
64
- >
65
- <AtomicText type="headlineMedium">Modal Content</AtomicText>
66
- </ScreenLayout>
67
- );
68
- }
69
-
70
- // 4. Screen with custom scroll behavior
71
- export function CustomScrollScreen() {
72
- return (
73
- <ScreenLayout scrollable={false}>
74
- {/* Your custom scroll component */}
75
- <View />
76
- </ScreenLayout>
77
- );
78
- }
79
-
80
- // 5. Using safe area hooks directly
81
- import { useContentSafeAreaPadding, useSafeAreaInsets } from '../../index';
82
-
83
- export function CustomComponent() {
84
- const insets = useSafeAreaInsets();
85
- const { paddingBottom } = useContentSafeAreaPadding();
86
-
87
- return (
88
- <View style={{ paddingTop: insets.top, paddingBottom }}>
89
- <Text>Custom Safe Area Usage</Text>
90
- </View>
91
- );
92
- }
@@ -1,129 +0,0 @@
1
- # CardMultimedia Types
2
-
3
- ## Purpose
4
- Type definitions for flashcard-specific media operations. These types define the contract for media attachment, generation, and management within the card-based learning system.
5
-
6
- ## File Location
7
- `src/domain/entities/CardMultimedia.types.ts`
8
-
9
- ## Strategy
10
- - Define the contract for card-specific media operations
11
- - Provide type-safe interfaces for flashcard media attachments
12
- - Support AI-powered media generation for educational content
13
- - Enable comprehensive media validation and optimization
14
- - Maintain clear separation between card media and general media types
15
- - Support upload progress tracking and compression
16
- - Facilitate media download management for offline learning
17
-
18
- ## Forbidden
19
- - **DO NOT** use these types for general-purpose media operations (use Multimedia types instead)
20
- - **DO NOT** include UI components or presentation logic in type definitions
21
- - **DO NOT** add business logic or implementation details to interfaces
22
- - **DO NOT** create circular dependencies with other domain types
23
- - **DO NOT** use `any` type or loose type definitions
24
- - **DO NOT** modify existing type properties - extend interfaces for new features
25
- - **DO NOT** assume specific storage backend or cloud provider
26
- - **DO NOT** hardcode validation limits in type definitions
27
- - **DO NOT** mix card media types with general multimedia types
28
-
29
- ## Rules
30
- 1. All card media types must be exported from this file
31
- 2. Type definitions must be framework-agnostic
32
- 3. Card media IDs must use "card_media_" prefix for uniqueness
33
- 4. Position types must explicitly define front/back/both placement
34
- 5. File size fields must use bytes as unit
35
- 6. Duration fields must use seconds as unit
36
- 7. Date fields must use ISO 8601 format
37
- 8. All generation requests must include input validation
38
- 9. Compression quality must be between 0.1 and 1.0
39
- 10. Upload progress must be tracked from 0-100
40
- 11. Validation results must separate errors, warnings, and recommendations
41
- 12. Service interfaces must return Promises for all async operations
42
- 13. Media type arrays must be automatically calculated, not manually set
43
- 14. Download status must be tracked per attachment
44
- 15. Estimated size must represent total of all attachments
45
-
46
- ## AI Agent Guidelines
47
-
48
- When working with CardMultimedia types:
49
-
50
- 1. **Type Selection**: Use CardMediaAttachment for flashcard-specific media operations
51
- 2. **Generation Requests**: Always specify input parameters and options explicitly
52
- 3. **Validation**: Validate media files before upload and after generation
53
- 4. **Progress Tracking**: Monitor upload progress for user feedback
54
- 5. **Compression**: Apply compression options before upload to reduce bandwidth
55
- 6. **Download Management**: Check isDownloaded status before displaying media
56
- 7. **Position Logic**: Respect position field for front/back/both placement
57
- 8. **Size Estimation**: Calculate total size for all media before batch operations
58
- 9. **Error Handling**: Parse validation errors and warnings for user feedback
59
- 10. **Cost Tracking**: Monitor creditsUsed for AI generation operations
60
-
61
- ### Key Types Reference
62
-
63
- - **CardMediaType**: "image" | "audio" | "video" - Media type classification for cards
64
- - **CardMediaPosition**: "front" | "back" | "both" - Display placement on card faces
65
- - **CardMediaAttachment**: Core interface for individual media items with metadata
66
- - **CardMultimediaFlashcard**: Card entity with computed media properties
67
- - **CardMediaGenerationRequest**: Input specification for AI media generation
68
- - **CardMediaGenerationResult**: Output with cost tracking and performance metrics
69
- - **CardMediaUploadProgress**: Real-time upload status tracking
70
- - **CardMediaCompressionOptions**: Quality and size optimization settings
71
- - **CardMediaValidation**: Comprehensive validation with recommendations
72
- - **CardMultimediaFlashcardService**: Service interface for media operations
73
-
74
- ### Type Usage Patterns
75
-
76
- 1. **CardMediaAttachment**: Individual media item with position, URL, and metadata
77
- 2. **CardMultimediaFlashcard**: Card with computed properties (hasMedia, mediaType, isDownloaded)
78
- 3. **CardMediaGenerationRequest**: Three generation types (text_to_image, text_to_audio, image_search)
79
- 4. **CardMediaValidation**: Separate errors (blocking) from warnings and recommendations
80
-
81
- ### Validation Rules
82
-
83
- 1. Validate file size against upload limits before processing
84
- 2. Check MIME type matches CardMediaType
85
- 3. Ensure dimensions are within supported ranges
86
- 4. Verify URIs are properly formatted and accessible
87
- 5. Validate duration for audio/video files
88
- 6. Check compression quality is within 0.1-1.0 range
89
- 7. Ensure generation prompts are non-empty strings
90
- 8. Validate language codes for audio generation (e.g., "tr-TR", "en-US")
91
-
92
- ### Service Interface Guidelines
93
-
94
- When implementing CardMultimediaFlashcardService:
95
-
96
- 1. **uploadMedia**: Accept file with optional compression, return attachment with URL
97
- 2. **generateMedia**: Process AI generation request, track credits and timing
98
- 3. **validateMedia**: Return comprehensive validation with errors, warnings, recommendations
99
- 4. **optimizeMedia**: Apply compression to existing attachment, preserve metadata
100
- 5. **deleteMedia**: Remove attachment and update card associations
101
- 6. **getMediaUrl**: Return accessible URL for downloaded or remote media
102
- 7. **downloadMedia**: Fetch remote media to local storage, update isDownloaded status
103
-
104
- ### Generation Type Specifics
105
-
106
- 1. **text_to_image**: Requires prompt, style (realistic/cartoon/artistic), quality, format
107
- 2. **text_to_audio**: Requires text, language, voice (male/female/neutral), format
108
- 3. **image_search**: Requires prompt, maxResults (no quality/format options)
109
-
110
- ### Position Logic
111
-
112
- 1. **front**: Media displayed only on card front face
113
- 2. **back**: Media displayed only on card back face
114
- 3. **both**: Media displayed on both card faces (e.g., background image)
115
-
116
- ### Download Management
117
-
118
- 1. Check isDownloaded before displaying media offline
119
- 2. Use localPath for offline access when available
120
- 3. Fall back to URL when media not downloaded
121
- 4. Track estimatedSize for storage management
122
- 5. Implement downloadMedia for offline caching
123
-
124
- ## Dependencies
125
-
126
- - No external dependencies
127
- - References domain types from Media.ts for base media concepts
128
- - Must be usable by infrastructure and presentation layers without additional dependencies
129
- - Service interfaces require async operation support