sojorn/sojorn_app/lib/models/tone_analysis.dart
Patrick Britton 3c4680bdd7 Initial commit: Complete threaded conversation system with inline replies
**Major Features Added:**
- **Inline Reply System**: Replace compose screen with inline reply boxes
- **Thread Navigation**: Parent/child navigation with jump functionality
- **Chain Flow UI**: Reply counts, expand/collapse animations, visual hierarchy
- **Enhanced Animations**: Smooth transitions, hover effects, micro-interactions

 **Frontend Changes:**
- **ThreadedCommentWidget**: Complete rewrite with animations and navigation
- **ThreadNode Model**: Added parent references and descendant counting
- **ThreadedConversationScreen**: Integrated navigation handlers
- **PostDetailScreen**: Replaced with threaded conversation view
- **ComposeScreen**: Added reply indicators and context
- **PostActions**: Fixed visibility checks for chain buttons

 **Backend Changes:**
- **API Route**: Added /posts/:id/thread endpoint
- **Post Repository**: Include allow_chain and visibility fields in feed
- **Thread Handler**: Support for fetching post chains

 **UI/UX Improvements:**
- **Reply Context**: Clear indication when replying to specific posts
- **Character Counting**: 500 character limit with live counter
- **Visual Hierarchy**: Depth-based indentation and styling
- **Smooth Animations**: SizeTransition, FadeTransition, hover states
- **Chain Navigation**: Parent/child buttons with visual feedback

 **Technical Enhancements:**
- **Animation Controllers**: Proper lifecycle management
- **State Management**: Clean separation of concerns
- **Navigation Callbacks**: Reusable navigation system
- **Error Handling**: Graceful fallbacks and user feedback

This creates a Reddit-style threaded conversation experience with smooth
animations, inline replies, and intuitive navigation between posts in a chain.
2026-01-30 07:40:19 -06:00

90 lines
2.3 KiB
Dart

/// Represents the tone analysis result from the AI moderation system.
///
/// The tone analysis uses intent-based detection rather than simple
/// keyword matching. This allows for authentic expression while
/// rejecting harmful content.
///
/// Note: This is used for real-time tone checking before posting.
/// See [ToneAnalysis] in post.dart for the stored post analysis.
class ToneCheckResult {
/// Whether content is flagged by moderation
final bool flagged;
/// The flagged category when present
final ModerationCategory? category;
/// List of flags detected in the content
final List<String> flags;
/// User-facing explanation of the analysis
final String reason;
ToneCheckResult({
required this.flagged,
required this.category,
required this.flags,
required this.reason,
});
factory ToneCheckResult.fromJson(Map<String, dynamic> json) {
return ToneCheckResult(
flagged: json['flagged'] == true,
category: ModerationCategory.fromString(json['category'] as String?),
flags: (json['flags'] as List<dynamic>?)
?.map((e) => e.toString())
.toList() ??
[],
reason: json['reason'] ?? 'Analysis complete',
);
}
/// Whether this content should be allowed
bool get isAllowed {
return !flagged;
}
String get categoryLabel {
switch (category) {
case ModerationCategory.bigotry:
return 'Bigotry';
case ModerationCategory.nsfw:
return 'NSFW';
case ModerationCategory.violence:
return 'Violence';
case null:
return 'Sensitive';
}
}
}
/// Possible moderation categories for content analysis
enum ModerationCategory {
bigotry,
nsfw,
violence;
static ModerationCategory? fromString(String? value) {
switch (value?.toLowerCase()) {
case 'bigotry':
return ModerationCategory.bigotry;
case 'nsfw':
return ModerationCategory.nsfw;
case 'violence':
return ModerationCategory.violence;
default:
return null;
}
}
}
/// Error thrown when tone analysis fails
class ToneCheckException implements Exception {
final String message;
final bool allowFallback;
ToneCheckException(this.message, {this.allowFallback = true});
@override
String toString() => 'ToneCheckException: $message';
}