Fix profile avatar and display name issues

- Increase Dio receiveTimeout to 120s for file uploads
- Reduce WebDAV client timeout to 30s
- Add cache-busting v parameter to avatar URLs
- Add hasChanges logic to disable Save button when no changes made
This commit is contained in:
Leon Bösche
2026-01-29 20:18:11 +01:00
parent bb7957cdde
commit e26f39ee5b
4 changed files with 16 additions and 5 deletions

View File

@@ -15,7 +15,7 @@ class ApiClient {
baseUrl: baseUrl,
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(
seconds: 60,
seconds: 120,
), // Increased for file uploads and org operations
),
);

View File

@@ -27,6 +27,7 @@ class _AccountSettingsDialogState extends State<AccountSettingsDialog> {
// Profile fields
late TextEditingController _displayNameController;
bool _hasChanges = false;
String? _avatarUrl;
// Security fields
@@ -55,6 +56,14 @@ class _AccountSettingsDialogState extends State<AccountSettingsDialog> {
}
}
});
// Listen for changes in display name
_displayNameController.addListener(() {
final newHasChanges = _displayNameController.text != (_currentUser?.displayName ?? '');
if (_hasChanges != newHasChanges) {
setState(() => _hasChanges = newHasChanges);
}
});
}
@override
@@ -168,6 +177,8 @@ class _AccountSettingsDialogState extends State<AccountSettingsDialog> {
const SnackBar(content: Text('Profile updated successfully')),
);
setState(() => _hasChanges = false);
// Close the dialog
Navigator.of(context).pop();
}
@@ -640,7 +651,7 @@ class _AccountSettingsDialogState extends State<AccountSettingsDialog> {
child: SizedBox(
width: 144,
child: ModernGlassButton(
onPressed: _isLoading ? () {} : () => _updateProfile(),
onPressed: _isLoading || !_hasChanges ? null : () => _updateProfile(),
isLoading: _isLoading,
child: _isLoading
? const SizedBox(

View File

@@ -3848,7 +3848,7 @@ func getUserProfileHandler(w http.ResponseWriter, r *http.Request, db *database.
// If avatar exists, return the backend URL instead of the internal WebDAV URL
if user.AvatarURL != nil && *user.AvatarURL != "" {
user.AvatarURL = &[]string{"/user/avatar"}[0]
user.AvatarURL = &[]string{fmt.Sprintf("/user/avatar?v=%d", time.Now().Unix())}[0]
}
w.Header().Set("Content-Type", "application/json")
@@ -4048,7 +4048,7 @@ func uploadUserAvatarHandler(w http.ResponseWriter, r *http.Request, db *databas
// Get public URL - for now, construct it manually since Nextcloud doesn't provide direct public URLs
// In a real setup, you'd configure Nextcloud to serve public URLs or use a CDN
publicURL := "/user/avatar"
publicURL := fmt.Sprintf("/user/avatar?v=%d", time.Now().Unix())
webdavURL := fmt.Sprintf("%s/%s", client.BaseURL, avatarPath)
// Update user profile with avatar URL

View File

@@ -42,7 +42,7 @@ func NewWebDAVClient(cfg *config.Config) *WebDAVClient {
user: cfg.NextcloudUser,
pass: cfg.NextcloudPass,
basePrefix: strings.TrimRight(base, "/"),
httpClient: &http.Client{Timeout: 120 * time.Second},
httpClient: &http.Client{Timeout: 30 * time.Second},
}
}