Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 67 additions & 11 deletions app/lib/pages/apps/explore_install_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -395,18 +395,74 @@ class ExploreInstallPageState extends State<ExploreInstallPage> with AutomaticKe
}

Widget _buildSearchLoadingSliver() {
return const SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 48),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
return SliverPadding(
padding: const EdgeInsets.only(bottom: 64, left: 20, right: 20, top: 20),
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => _buildShimmerListItem(),
childCount: 5, // Show 5 shimmer items
),
),
);
}

Widget _buildShimmerListItem() {
return Shimmer.fromColors(
baseColor: AppStyles.backgroundSecondary,
highlightColor: AppStyles.backgroundTertiary,
child: Container(
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.only(bottom: 8),
decoration: BoxDecoration(
color: AppStyles.backgroundSecondary,
borderRadius: BorderRadius.circular(16),
),
child: Row(
children: [
SizedBox(height: 8),
CircularProgressIndicator(color: Colors.deepPurpleAccent, strokeWidth: 2),
SizedBox(height: 12),
Text(
'Searching...',
style: TextStyle(color: Colors.white70, fontSize: 14),
// App icon shimmer
Container(
width: 60,
height: 60,
decoration: BoxDecoration(
color: AppStyles.backgroundTertiary,
borderRadius: BorderRadius.circular(12),
),
),
const SizedBox(width: 16),
// App info shimmer
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
height: 18,
decoration: BoxDecoration(
color: AppStyles.backgroundTertiary,
borderRadius: BorderRadius.circular(4),
),
),
const SizedBox(height: 8),
Container(
width: 150,
height: 14,
decoration: BoxDecoration(
color: AppStyles.backgroundTertiary,
borderRadius: BorderRadius.circular(4),
),
),
],
),
),
const SizedBox(width: 12),
// Button shimmer
Container(
width: 72,
height: 32,
decoration: BoxDecoration(
color: AppStyles.backgroundTertiary,
borderRadius: BorderRadius.circular(16),
),
),
],
),
Expand Down
8 changes: 1 addition & 7 deletions app/lib/pages/apps/list_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,13 @@ class AppListItem extends StatelessWidget {
// Use Selector to only rebuild when this specific app's state or loading state changes
return Selector<AppProvider, ({bool enabled, bool isLoading})>(
selector: (context, provider) {
// Find the current app state
final currentApp = provider.apps.firstWhere(
(a) => a.id == app.id,
orElse: () => app,
);

// Check if this specific app is loading
final isLoading = index != -1 &&
provider.appLoading.isNotEmpty &&
index < provider.appLoading.length &&
provider.appLoading[index];

return (enabled: currentApp.enabled, isLoading: isLoading);
return (enabled: app.enabled, isLoading: isLoading);
},
builder: (context, state, child) {
return GestureDetector(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:async';
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_provider_utilities/flutter_provider_utilities.dart';
import 'package:omi/backend/http/api/apps.dart';
import 'package:omi/backend/http/api/conversations.dart';
import 'package:omi/backend/http/api/users.dart';
import 'package:omi/utils/platform/platform_manager.dart';
Expand Down Expand Up @@ -313,6 +314,17 @@ class ConversationDetailProvider extends ChangeNotifier with MessageNotifierMixi
}
}

/// Returns the list of enabled apps that support conversations from the API
Future<List<App>> getEnabledConversationAppsFromAPI() async {
try {
final result = await retrieveAppsSearch(installedApps: true, limit: 100);
return result.apps.where((app) => app.worksWithMemories() && app.enabled).toList();
} catch (e) {
debugPrint('Error fetching enabled conversation apps: $e');
return [];
}
}

/// Checks if an app is in the suggested apps list
bool isAppSuggested(String appId) {
return getSuggestedApps().contains(appId);
Expand Down
Loading