Skip to content

Commit 07fd2b4

Browse files
committed
Remove hard-coded path names related to HealthPod
1 parent d3489ea commit 07fd2b4

7 files changed

Lines changed: 153 additions & 229 deletions

lib/src/models/data_format_config.dart

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -97,45 +97,3 @@ class DataFormatConfig {
9797
description.hashCode;
9898
}
9999
}
100-
101-
/// Pre-defined format configurations for common health data types.
102-
103-
class SolidFileDataFormats {
104-
static const bloodPressure = DataFormatConfig(
105-
title: 'Blood Pressure CSV Format',
106-
requiredFields: ['timestamp', 'systolic', 'diastolic', 'heart_rate'],
107-
optionalFields: ['notes'],
108-
);
109-
110-
static const vaccination = DataFormatConfig(
111-
title: 'Vaccination CSV Format',
112-
requiredFields: ['timestamp', 'name', 'type'],
113-
optionalFields: ['location', 'notes', 'batch_number'],
114-
);
115-
116-
static const medication = DataFormatConfig(
117-
title: 'Medication CSV Format',
118-
requiredFields: ['timestamp', 'name', 'dosage', 'frequency', 'start_date'],
119-
optionalFields: ['notes'],
120-
);
121-
122-
static const diary = DataFormatConfig(
123-
title: 'Appointment CSV Format',
124-
requiredFields: ['timestamp', 'content'],
125-
optionalFields: ['mood', 'tags', 'notes'],
126-
);
127-
128-
static const profile = DataFormatConfig(
129-
title: 'Profile JSON Format',
130-
requiredFields: [
131-
'name',
132-
'address',
133-
'bestContactPhone',
134-
'alternativeContactNumber',
135-
'email',
136-
'dateOfBirth',
137-
'gender',
138-
],
139-
isJson: true,
140-
);
141-
}

lib/src/models/file_type_config.dart

Lines changed: 50 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -33,23 +33,25 @@ import 'package:solidui/src/utils/path_utils.dart';
3333
import 'package:solidui/src/widgets/solid_file_helpers.dart';
3434
import 'package:solidui/src/widgets/solid_file_upload_config.dart';
3535

36-
/// Predefined file types for different data categories.
37-
38-
enum SolidFileType {
39-
bloodPressure,
40-
vaccination,
41-
medication,
42-
diary,
43-
profile,
44-
general,
45-
}
36+
/// A callback type for resolving file type configurations from a path.
37+
///
38+
/// Applications can provide their own resolver to map directory paths to
39+
/// specific [FileTypeConfig] instances. Return `null` to fall through to the
40+
/// default generic behaviour.
41+
42+
typedef FileTypeResolver = FileTypeConfig? Function(
43+
String normalisedPath,
44+
String? basePath,
45+
);
4646

4747
/// Configuration for different file types.
4848
4949
class FileTypeConfig {
50-
/// The file type.
50+
/// A string identifier for this file type (e.g. 'general', 'blood_pressure').
51+
///
52+
/// Applications may define their own type identifiers.
5153
52-
final SolidFileType type;
54+
final String typeId;
5355

5456
/// Display name for the folder.
5557
@@ -84,7 +86,7 @@ class FileTypeConfig {
8486
final String uploadTooltip;
8587

8688
const FileTypeConfig({
87-
required this.type,
89+
this.typeId = 'general',
8890
required this.displayName,
8991
this.showCsvButtons = false,
9092
this.showProfileButtons = false,
@@ -97,121 +99,58 @@ class FileTypeConfig {
9799

98100
/// Gets the file type configuration based on the current path.
99101
100-
static FileTypeConfig fromPath(String currentPath, [String? basePath]) {
102+
static FileTypeConfig fromPath(
103+
String currentPath, [
104+
String? basePath,
105+
FileTypeResolver? resolver,
106+
]) {
101107
// Normalise the path for consistent pattern matching.
102108

103109
final normalisedPath = PathUtils.normalise(currentPath);
104110

105-
if (normalisedPath.contains('/blood_pressure') ||
106-
normalisedPath.contains('blood_pressure/') ||
107-
normalisedPath.endsWith('blood_pressure')) {
108-
return const FileTypeConfig(
109-
type: SolidFileType.bloodPressure,
110-
displayName: 'Blood Pressure Data',
111-
showCsvButtons: true,
112-
formatConfig: SolidFileDataFormats.bloodPressure,
113-
uploadTooltip: '''
111+
// Attempt app-specific resolution first.
114112

115-
**Upload**: Tap here to upload a file to your Solid Health Pod.
113+
if (resolver != null) {
114+
final resolved = resolver(normalisedPath, basePath);
115+
if (resolved != null) return resolved;
116+
}
116117

117-
''',
118-
);
119-
} else if (normalisedPath.contains('/vaccination') ||
120-
normalisedPath.contains('vaccination/') ||
121-
normalisedPath.endsWith('vaccination')) {
122-
return const FileTypeConfig(
123-
type: SolidFileType.vaccination,
124-
displayName: 'Vaccination Data',
125-
showCsvButtons: true,
126-
formatConfig: SolidFileDataFormats.vaccination,
127-
uploadTooltip: '''
128-
129-
**Upload**: Tap here to upload a file to your Solid Health Pod.
118+
// Generic fallback — derive a friendly display name from the path.
130119

131-
''',
132-
);
133-
} else if (normalisedPath.contains('/medication') ||
134-
normalisedPath.contains('medication/') ||
135-
normalisedPath.endsWith('medication')) {
136-
return const FileTypeConfig(
137-
type: SolidFileType.medication,
138-
displayName: 'Medication Data',
139-
showCsvButtons: true,
140-
formatConfig: SolidFileDataFormats.medication,
141-
uploadTooltip: '''
142-
143-
**Upload**: Tap here to upload a file to your Solid Health Pod.
120+
String effectiveBasePath =
121+
basePath != null ? PathUtils.normalise(basePath) : '';
144122

145-
''',
146-
);
147-
} else if (normalisedPath.contains('/diary') ||
148-
normalisedPath.contains('diary/') ||
149-
normalisedPath.endsWith('diary')) {
150-
return const FileTypeConfig(
151-
type: SolidFileType.diary,
152-
displayName: 'Appointments Data',
153-
showCsvButtons: true,
154-
formatConfig: SolidFileDataFormats.diary,
155-
uploadTooltip: '''
156-
157-
**Upload**: Tap here to upload a file to your Solid Health Pod.
123+
if (effectiveBasePath.isEmpty) {
124+
final segments =
125+
normalisedPath.split('/').where((s) => s.isNotEmpty).toList();
158126

159-
''',
160-
);
161-
} else if (normalisedPath.contains('/profile') ||
162-
normalisedPath.contains('profile/') ||
163-
normalisedPath.endsWith('profile')) {
164-
return const FileTypeConfig(
165-
type: SolidFileType.profile,
166-
displayName: 'Profile Data',
167-
showProfileButtons: true,
168-
formatConfig: SolidFileDataFormats.profile,
169-
uploadTooltip: '''
170-
171-
**Upload**: Tap here to upload a file to your Solid Health Pod.
127+
// Construct a reasonable base path — typically the first 2 segments
128+
// for most cases.
172129

173-
''',
174-
);
175-
} else {
176-
// General case - use the existing friendly folder name logic for
177-
// consistency. If basePath is provided, use it; otherwise, construct a
178-
// reasonable default.
179-
180-
String effectiveBasePath =
181-
basePath != null ? PathUtils.normalise(basePath) : '';
182-
183-
if (effectiveBasePath.isEmpty) {
184-
final segments =
185-
normalisedPath.split('/').where((s) => s.isNotEmpty).toList();
186-
187-
// Construct a reasonable base path - typically the first 2 segments
188-
// for most cases.
189-
190-
if (segments.length >= 2) {
191-
effectiveBasePath = '${segments[0]}/${segments[1]}';
192-
} else if (segments.length == 1) {
193-
effectiveBasePath = segments[0];
194-
}
130+
if (segments.length >= 2) {
131+
effectiveBasePath = '${segments[0]}/${segments[1]}';
132+
} else if (segments.length == 1) {
133+
effectiveBasePath = segments[0];
195134
}
135+
}
196136

197-
final friendlyName = SolidFileHelpers.getFriendlyFolderName(
198-
normalisedPath,
199-
effectiveBasePath,
200-
);
137+
final friendlyName = SolidFileHelpers.getFriendlyFolderName(
138+
normalisedPath,
139+
effectiveBasePath,
140+
);
201141

202-
String displayName =
203-
friendlyName == 'Home' ? 'Home Folder' : friendlyName;
142+
String displayName =
143+
friendlyName == 'Home' ? 'Home Folder' : friendlyName;
204144

205-
return FileTypeConfig(
206-
type: SolidFileType.general,
207-
displayName: displayName,
208-
uploadTooltip: '''
145+
return FileTypeConfig(
146+
typeId: 'general',
147+
displayName: displayName,
148+
uploadTooltip: '''
209149
210-
**Upload**: Tap here to upload a file to your Solid Health Pod.
150+
**Upload**: Tap here to upload a file to your Solid Pod.
211151
212152
''',
213-
);
214-
}
153+
);
215154
}
216155

217156
/// Creates the upload configuration for this file type.

lib/src/widgets/solid_file.dart

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import 'package:flutter/material.dart';
3232

3333
import 'package:solidpod/solidpod.dart' show getDataDirPath;
3434

35+
import 'package:solidui/src/models/file_type_config.dart';
3536
import 'package:solidui/src/utils/path_utils.dart';
3637
import 'package:solidui/src/widgets/solid_file_browser.dart';
3738
import 'package:solidui/src/widgets/solid_file_browser_builder.dart';
@@ -123,6 +124,23 @@ class SolidFile extends StatefulWidget {
123124
124125
final bool autoConfig;
125126

127+
/// Optional resolver for mapping paths to file type configurations.
128+
///
129+
/// Applications can supply their own resolver to provide custom upload
130+
/// configurations, display names, and format configs based on the current
131+
/// directory path. When the resolver returns `null`, the generic default
132+
/// behaviour is used.
133+
134+
final FileTypeResolver? fileTypeResolver;
135+
136+
/// Optional map of directory basenames to display names.
137+
///
138+
/// When provided, the file browser uses these overrides to display
139+
/// user-friendly folder names (e.g. `{'blood_pressure': 'Blood Pressure
140+
/// Data'}`). Entries not found in the map fall back to generic formatting.
141+
142+
final Map<String, String>? folderNameOverrides;
143+
126144
const SolidFile({
127145
super.key,
128146
this.currentPath,
@@ -144,6 +162,8 @@ class SolidFile extends StatefulWidget {
144162
this.uploadState,
145163
this.browserKey,
146164
this.autoConfig = true,
165+
this.fileTypeResolver,
166+
this.folderNameOverrides,
147167
});
148168

149169
/// Legacy constructor for backward compatibility.
@@ -154,6 +174,8 @@ class SolidFile extends StatefulWidget {
154174
required SolidFileCallbacks callbacks,
155175
required SolidFileState state,
156176
this.browserKey,
177+
this.fileTypeResolver,
178+
this.folderNameOverrides,
157179
}) : currentPath = state.currentPath,
158180
friendlyFolderName = state.friendlyFolderName,
159181
showBackButton = config.showBackButton,
@@ -355,6 +377,7 @@ class _SolidFileState extends State<SolidFile> {
355377
widget.autoConfig,
356378
widget.showUpload,
357379
widget.uploadConfig,
380+
widget.fileTypeResolver,
358381
),
359382
uploadCallbacks: _getEffectiveUploadCallbacks(),
360383
uploadState: widget.uploadState ??
@@ -372,6 +395,7 @@ class _SolidFileState extends State<SolidFile> {
372395
widget.autoConfig,
373396
widget.showUpload,
374397
widget.uploadConfig,
398+
widget.fileTypeResolver,
375399
),
376400
uploadCallbacks: _getEffectiveUploadCallbacks(),
377401
uploadState: widget.uploadState ??
@@ -400,6 +424,7 @@ class _SolidFileState extends State<SolidFile> {
400424
_effectiveBasePath,
401425
widget.autoConfig,
402426
widget.friendlyFolderName,
427+
widget.fileTypeResolver,
403428
),
404429
initialPath: widget.currentPath,
405430
onFileSelected: widget.onFileSelected,
@@ -408,6 +433,7 @@ class _SolidFileState extends State<SolidFile> {
408433
onImportCsv: widget.onImportCsv,
409434
onDirectoryChanged: _handleDirectoryChanged,
410435
uploadCallbacks: widget.uploadCallbacks,
436+
folderNameOverrides: widget.folderNameOverrides,
411437
);
412438
}
413439
}

lib/src/widgets/solid_file_browser.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ class SolidFileBrowser extends StatefulWidget {
8181
8282
final String? initialPath;
8383

84+
/// Optional map of directory basenames to display names.
85+
///
86+
/// When provided, these overrides are used to display user-friendly folder
87+
/// names in the path bar. Entries not found in the map fall back to generic
88+
/// formatting.
89+
90+
final Map<String, String>? folderNameOverrides;
91+
8492
const SolidFileBrowser({
8593
super.key,
8694
required this.onFileSelected,
@@ -91,6 +99,7 @@ class SolidFileBrowser extends StatefulWidget {
9199
required this.onDirectoryChanged,
92100
required this.friendlyFolderName,
93101
this.initialPath,
102+
this.folderNameOverrides,
94103
});
95104

96105
@override
@@ -348,6 +357,7 @@ class SolidFileBrowserState extends State<SolidFileBrowser> {
348357
return SolidFileOperations.getFriendlyFolderName(
349358
currentPath,
350359
_homePath,
360+
widget.folderNameOverrides,
351361
);
352362
}
353363

lib/src/widgets/solid_file_browser_builder.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,14 @@ class SolidFileBrowserBuilder {
4949
Function(String fileName, String filePath)? onImportCsv,
5050
required Function(String path) onDirectoryChanged,
5151
SolidFileUploadCallbacks? uploadCallbacks,
52+
Map<String, String>? folderNameOverrides,
5253
}) {
5354
return SolidFileBrowser(
5455
key: browserKey,
5556
browserKey: browserKey,
5657
friendlyFolderName: friendlyFolderName,
5758
initialPath: initialPath,
59+
folderNameOverrides: folderNameOverrides,
5860
onFileSelected: onFileSelected ??
5961
(fileName, filePath) {
6062
debugPrint('File selected: $fileName at $filePath');

0 commit comments

Comments
 (0)