122 lines
3.2 KiB
Dart
122 lines
3.2 KiB
Dart
import 'package:didvan/constants/assets.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
enum MediaType { image, video, gif }
|
|
|
|
// Represents a single story item (image, gif, or video)
|
|
class StoryItem {
|
|
final int id;
|
|
final String url;
|
|
final MediaType media;
|
|
final Duration duration;
|
|
final ValueNotifier<bool> isViewed;
|
|
|
|
StoryItem({
|
|
required this.id,
|
|
required this.url,
|
|
required this.media,
|
|
required this.duration,
|
|
bool viewed = false,
|
|
}) : isViewed = ValueNotifier(viewed);
|
|
|
|
factory StoryItem.fromJson(Map<String, dynamic> json) {
|
|
MediaType mediaType;
|
|
switch (json['mediaType']) {
|
|
case 'VIDEO':
|
|
mediaType = MediaType.video;
|
|
break;
|
|
case 'GIF':
|
|
mediaType = MediaType.gif;
|
|
break;
|
|
case 'IMAGE':
|
|
default:
|
|
mediaType = MediaType.image;
|
|
break;
|
|
}
|
|
|
|
return StoryItem(
|
|
id: json['id'],
|
|
url: json['mediaUrl'],
|
|
media: mediaType,
|
|
// API doesn't provide duration for images/gifs, so we use a default.
|
|
// For videos, the player controller will determine the duration.
|
|
duration: const Duration(seconds: 10),
|
|
);
|
|
}
|
|
}
|
|
|
|
class User {
|
|
final String name;
|
|
final String profileImageUrl;
|
|
final String createdAt;
|
|
|
|
const User({
|
|
required this.name,
|
|
required this.profileImageUrl,
|
|
required this.createdAt,
|
|
});
|
|
}
|
|
|
|
// This class will wrap the API response and fit it into the UI's expected structure.
|
|
class UserStories {
|
|
final int id; // The main story ID from the API
|
|
final User user;
|
|
final List<StoryItem> stories;
|
|
|
|
UserStories({
|
|
required this.id,
|
|
required this.user,
|
|
required this.stories,
|
|
});
|
|
|
|
factory UserStories.fromApiJson(Map<String, dynamic> json) {
|
|
final List<dynamic> items = json['items'] ?? [];
|
|
final List<dynamic> completedIds = json['completedStoryItemIds'] ?? [];
|
|
|
|
return UserStories(
|
|
id: json['id'],
|
|
user: User(
|
|
name: json['title'], // Using title directly from the API
|
|
profileImageUrl:
|
|
_mapCategoryToIcon(json['category']), // Mapping category to an icon
|
|
createdAt: json['createdAt'],
|
|
),
|
|
stories: items.map((item) {
|
|
final storyItem = StoryItem.fromJson(item);
|
|
// Check if this story item has been viewed.
|
|
if (completedIds.contains(storyItem.id)) {
|
|
storyItem.isViewed.value = true;
|
|
}
|
|
return storyItem;
|
|
}).toList(),
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
String _mapCategoryToIcon(String category) {
|
|
switch (category) {
|
|
case 'MACRO_TRENDS':
|
|
return 'lib/assets/icons/MACRO_TRENDS.svg';
|
|
case 'INDUSTRY_ENVIRONMENT':
|
|
return 'lib/assets/icons/INDUSTRY_ENVIRONMENT.svg';
|
|
case 'COMPETITION_ENVIRONMENT':
|
|
return Assets.startup;
|
|
case 'OPPORTUNITIES':
|
|
return Assets.hugeideas;
|
|
case 'THREATS':
|
|
return Assets.risk;
|
|
case 'TECHNOLOGY':
|
|
return Assets.tech;
|
|
case 'STARTUPS':
|
|
return Assets.startup;
|
|
case 'CONCEPTS':
|
|
return 'lib/assets/icons/CONCEPTS.svg';
|
|
case 'MACRO_ENVIRONMENT':
|
|
return 'lib/assets/icons/MACRO_ENVIRONMENT.svg';
|
|
case 'MODERN_INVESTMENTS':
|
|
return 'lib/assets/icons/MODERN_INVESTMENTS.svg';
|
|
default:
|
|
return Assets.stats;
|
|
}
|
|
} |