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
25 changes: 25 additions & 0 deletions lib/core/misc/custom_types/int_or_string.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2025 BitCodersNN

sealed class IntOrString {
Object get value;
String get stringValue;
}

final class IntValue extends IntOrString {
@override
final int value;
IntValue(this.value);

@override
String get stringValue => value.toString();
}

final class StringValue extends IntOrString {
@override
final String value;
StringValue(this.value);

@override
String get stringValue => value;
}
6 changes: 4 additions & 2 deletions lib/core/models/dialog/base_dialog_info.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2025 BitCodersNN

import 'package:unn_mobile/core/misc/custom_types/int_or_string.dart';

abstract class BaseDialogInfo {
final int chatId;
final IntOrString dialogId;
final String title;
final String avatarUrl;

BaseDialogInfo({
required this.chatId,
required this.dialogId,
required this.title,
required this.avatarUrl,
});
Expand Down
19 changes: 16 additions & 3 deletions lib/core/models/dialog/dialog.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2025 BitCodersNN

import 'package:unn_mobile/core/misc/custom_types/int_or_string.dart';
import 'package:unn_mobile/core/misc/enum_from_string.dart';
import 'package:unn_mobile/core/misc/json/json_utils.dart';
import 'package:unn_mobile/core/models/dialog/base_dialog_info.dart';
import 'package:unn_mobile/core/models/dialog/enum/message_status.dart';
import 'package:unn_mobile/core/models/dialog/message/message_short_info.dart';

class _DialogJsonKeys {
static const String dialogId = 'id';
static const String chatId = 'chat_id';
static const String title = 'title';
static const String avatar = 'avatar';
Expand All @@ -23,6 +25,7 @@ class _DialogJsonKeys {
}

class Dialog extends BaseDialogInfo {
final int chatId;
final MessageShortInfo previewMessage;
final MessageStatus lastMessageStatus;
final int unreadMessagesCount;
Expand All @@ -36,9 +39,10 @@ class Dialog extends BaseDialogInfo {
}

Dialog({
required super.chatId,
required super.dialogId,
required super.title,
required super.avatarUrl,
required this.chatId,
required this.previewMessage,
required this.lastMessageStatus,
required this.unreadMessagesCount,
Expand All @@ -53,11 +57,20 @@ class Dialog extends BaseDialogInfo {
final fileName = (fileInfo as JsonMap)[_DialogJsonKeys.name]! as String;
messageMap[_DialogJsonKeys.text] = 'Файл: $fileName';
}
final IntOrString dialogId = switch (jsonMap[_DialogJsonKeys.dialogId]!) {
final int value => IntValue(value),
final String value => StringValue(value),
_ => throw ArgumentError(
'Expected int or String',
),
};

return Dialog(
chatId: jsonMap[_DialogJsonKeys.chatId]! as int,
dialogId: dialogId,
title: jsonMap[_DialogJsonKeys.title]! as String,
avatarUrl: (jsonMap[_DialogJsonKeys.avatar]!
as JsonMap)[_DialogJsonKeys.url]! as String,
chatId: jsonMap[_DialogJsonKeys.chatId]! as int,
previewMessage: MessageShortInfo.fromJson({
...messageMap,
MessageShortInfoJsonKeys.author: jsonMap[_DialogJsonKeys.user],
Expand All @@ -75,7 +88,7 @@ class Dialog extends BaseDialogInfo {
final messageMap = previewMessage.toJson();

return {
_DialogJsonKeys.chatId: chatId,
_DialogJsonKeys.dialogId: dialogId.value,
_DialogJsonKeys.title: title,
_DialogJsonKeys.avatar: {
_DialogJsonKeys.url: avatarUrl,
Expand Down
9 changes: 4 additions & 5 deletions lib/core/models/dialog/group_dialog.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2025 BitCodersNN

import 'package:unn_mobile/core/misc/custom_types/int_or_string.dart';
import 'package:unn_mobile/core/misc/json/json_utils.dart';
import 'package:unn_mobile/core/models/dialog/chat_settings/calendar_chat_setting.dart';
import 'package:unn_mobile/core/models/dialog/chat_settings/chat_setting.dart';
Expand All @@ -16,33 +17,32 @@ class GroupDialogJsonKeys {
}

final class GroupDialog extends Dialog {
final String dialogId;
final ChatSetting chatSetting;

GroupDialog({
required super.dialogId,
required super.chatId,
required super.title,
required super.avatarUrl,
required super.previewMessage,
required super.unreadMessagesCount,
required super.lastMessageStatus,
required super.pinned,
required this.dialogId,
required this.chatSetting,
});

factory GroupDialog.fromJson(JsonMap json) {
final dialog = Dialog.fromJson(json);

return GroupDialog(
chatId: dialog.chatId,
title: dialog.title,
avatarUrl: dialog.avatarUrl,
previewMessage: dialog.previewMessage,
unreadMessagesCount: dialog.unreadMessagesCount,
lastMessageStatus: dialog.lastMessageStatus,
pinned: dialog.pinned,
dialogId: json[GroupDialogJsonKeys.id]! as String,
chatId: dialog.chatId,
dialogId: StringValue(json[GroupDialogJsonKeys.id]! as String),
chatSetting:
_parseChatSetting(json[GroupDialogJsonKeys.chat]! as JsonMap),
);
Expand All @@ -51,7 +51,6 @@ final class GroupDialog extends Dialog {
@override
JsonMap toJson() => {
...super.toJson(),
GroupDialogJsonKeys.id: dialogId,
GroupDialogJsonKeys.chat: chatSetting.toJson(),
GroupDialogJsonKeys.type: GroupDialogJsonKeys.chat,
};
Expand Down
15 changes: 10 additions & 5 deletions lib/core/models/dialog/preview_dialog.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2025 BitCodersNN

import 'package:unn_mobile/core/misc/custom_types/int_or_string.dart';
import 'package:unn_mobile/core/misc/json/json_utils.dart';
import 'package:unn_mobile/core/models/dialog/base_dialog_info.dart';

Expand All @@ -13,21 +14,25 @@ class _PreviewDialogJsonKeys {

class PreviewDialog extends BaseDialogInfo {
PreviewDialog({
required super.chatId,
required super.dialogId,
required super.title,
required super.avatarUrl,
});

factory PreviewDialog.fromJson(JsonMap json) => PreviewDialog(
chatId: (json[_PreviewDialogJsonKeys.customData]!
as JsonMap)[_PreviewDialogJsonKeys.id]! as int,
factory PreviewDialog.fromJson(JsonMap json, {required bool idIsString}) =>
PreviewDialog(
dialogId: idIsString
? StringValue(json[_PreviewDialogJsonKeys.id]! as String)
: IntValue(
int.tryParse(json[_PreviewDialogJsonKeys.id]! as String)!,
),
title: json[_PreviewDialogJsonKeys.title]! as String,
avatarUrl: json[_PreviewDialogJsonKeys.avatar]! as String,
);

JsonMap toJson() => {
_PreviewDialogJsonKeys.customData: {
_PreviewDialogJsonKeys.id: chatId,
_PreviewDialogJsonKeys.id: dialogId,
},
_PreviewDialogJsonKeys.title: title,
_PreviewDialogJsonKeys.avatar: avatarUrl,
Expand Down
11 changes: 3 additions & 8 deletions lib/core/models/dialog/preview_group_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,26 @@ import 'package:unn_mobile/core/models/dialog/chat_settings/base_chat_setting.da
import 'package:unn_mobile/core/models/dialog/preview_dialog.dart';

class _PreviewGroupDialogJsonKeys {
static const String id = 'id';
static const String customData = 'customData';
}

class PreviewGroupDialog extends PreviewDialog {
final String id;
final BaseChatSetting baseChatSetting;

PreviewGroupDialog({
required super.chatId,
required super.dialogId,
required super.title,
required super.avatarUrl,
required this.id,
required this.baseChatSetting,
});

factory PreviewGroupDialog.fromJson(JsonMap json) {
final dialog = PreviewDialog.fromJson(json);
final dialog = PreviewDialog.fromJson(json, idIsString: true);

return PreviewGroupDialog(
chatId: dialog.chatId,
dialogId: dialog.dialogId,
title: dialog.title,
avatarUrl: dialog.avatarUrl,
id: json[_PreviewGroupDialogJsonKeys.id]! as String,
baseChatSetting: BaseChatSetting.fromJson(
json[_PreviewGroupDialogJsonKeys.customData]! as JsonMap,
),
Expand All @@ -44,7 +40,6 @@ class PreviewGroupDialog extends PreviewDialog {

return {
...superJson,
_PreviewGroupDialogJsonKeys.id: id,
_PreviewGroupDialogJsonKeys.customData: {
...existingCustomData,
...baseChatSetting.toJson(),
Expand Down
6 changes: 3 additions & 3 deletions lib/core/models/dialog/preview_user_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@ class PreviewUserDialog extends PreviewDialog {
final String workPosition;

PreviewUserDialog({
required super.chatId,
required super.dialogId,
required super.title,
required super.avatarUrl,
required this.lastActivityAt,
required this.workPosition,
});

factory PreviewUserDialog.fromJson(JsonMap json) {
final dialog = PreviewDialog.fromJson(json);
final dialog = PreviewDialog.fromJson(json, idIsString: false);
final lastActivityAt = (json[_PreviewUserDialogJsonKeys.customData]!
as JsonMap)[_PreviewUserDialogJsonKeys.lastActivityDate];
return PreviewUserDialog(
chatId: dialog.chatId,
dialogId: dialog.dialogId,
title: dialog.title,
avatarUrl: dialog.avatarUrl,
lastActivityAt:
Expand Down
7 changes: 2 additions & 5 deletions lib/core/models/dialog/user_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,37 @@ import 'package:unn_mobile/core/misc/json/json_utils.dart';
import 'package:unn_mobile/core/models/dialog/dialog.dart';

class _UserDialogJsonKeys {
static const String id = 'id';
static const String type = 'type';
static const String user = 'user';
static const String lastActivityDate = 'last_activity_date';
}

final class UserDialog extends Dialog {
final int dialogId;
final DateTime? lastActivityAt;

UserDialog({
required super.dialogId,
required super.chatId,
required super.title,
required super.avatarUrl,
required super.previewMessage,
required super.unreadMessagesCount,
required super.lastMessageStatus,
required super.pinned,
required this.dialogId,
required this.lastActivityAt,
});

factory UserDialog.fromJson(JsonMap json) {
final dialog = Dialog.fromJson(json);
return UserDialog(
dialogId: dialog.dialogId,
chatId: dialog.chatId,
title: dialog.title,
avatarUrl: dialog.avatarUrl,
previewMessage: dialog.previewMessage,
unreadMessagesCount: dialog.unreadMessagesCount,
lastMessageStatus: dialog.lastMessageStatus,
pinned: dialog.pinned,
dialogId: json[_UserDialogJsonKeys.id]! as int,
lastActivityAt: DateTime.tryParse(
(json[_UserDialogJsonKeys.user]!
as JsonMap)[_UserDialogJsonKeys.lastActivityDate]! as String,
Expand All @@ -48,7 +46,6 @@ final class UserDialog extends Dialog {
@override
JsonMap toJson() => {
...super.toJson(),
_UserDialogJsonKeys.id: dialogId,
_UserDialogJsonKeys.type: _UserDialogJsonKeys.user,
_UserDialogJsonKeys.user: {
_UserDialogJsonKeys.lastActivityDate:
Expand Down
2 changes: 1 addition & 1 deletion lib/core/models/distance_learning/semester.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import 'package:flutter/material.dart';
import 'package:unn_mobile/core/constants/academic_year.dart';
import 'package:unn_mobile/core/misc/bounded_int.dart';
import 'package:unn_mobile/core/misc/custom_types/bounded_int.dart';
import 'package:unn_mobile/core/misc/date_time_utilities/date_time_extensions.dart';
import 'package:unn_mobile/core/misc/json/json_utils.dart';

Expand Down
2 changes: 1 addition & 1 deletion lib/core/models/profile/search_filter.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2025 BitCodersNN

import 'package:unn_mobile/core/misc/bounded_int.dart';
import 'package:unn_mobile/core/misc/camel_case_converter.dart';
import 'package:unn_mobile/core/misc/custom_types/bounded_int.dart';

typedef FilterMap = Map<String, dynamic>;

Expand Down
19 changes: 6 additions & 13 deletions lib/core/viewmodels/main_page/chat/chat_inside_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ import 'package:unn_mobile/core/misc/objects_with_pagination.dart';
import 'package:unn_mobile/core/misc/user/current_user_sync_storage.dart';
import 'package:unn_mobile/core/models/common/file_data.dart';
import 'package:unn_mobile/core/models/dialog/dialog.dart';
import 'package:unn_mobile/core/models/dialog/group_dialog.dart';
import 'package:unn_mobile/core/models/dialog/message/enum/message_state.dart';
import 'package:unn_mobile/core/models/dialog/message/message.dart';
import 'package:unn_mobile/core/models/dialog/user_dialog.dart';
import 'package:unn_mobile/core/viewmodels/base_view_model.dart';
import 'package:unn_mobile/core/viewmodels/factories/main_page_routes_view_models_factory.dart';
import 'package:unn_mobile/core/viewmodels/main_page/chat/chat_screen_view_model.dart';
Expand Down Expand Up @@ -185,23 +183,18 @@ class ChatInsideViewModel extends BaseViewModel {
);

FutureOr<bool> sendMessage(String text) async =>
await _sendMessageWrapper<int>(() async {
final dialogId = switch (_dialog) {
final UserDialog userDialog => userDialog.dialogId.toString(),
final GroupDialog groupDialog => groupDialog.dialogId,
_ => '',
};
return _replyMessage == null
await _sendMessageWrapper<int>(
() async => _replyMessage == null
? await _messagesAggregator.send(
dialogId: dialogId,
dialogId: _dialog?.dialogId.stringValue ?? '',
text: text,
)
: await _messagesAggregator.reply(
dialogId: dialogId,
dialogId: _dialog?.dialogId.stringValue ?? '',
text: text,
replyMessageId: _replyMessage!.messageId,
);
});
),
);

FutureOr<void> _init(int chatId) async {
_hasError = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider_plus/carousel_slider_plus.dart';
import 'package:extended_image/extended_image.dart';
import 'package:flutter/material.dart';
import 'package:unn_mobile/core/misc/bounded_int.dart';
import 'package:unn_mobile/core/misc/custom_types/bounded_int.dart';
import 'package:unn_mobile/ui/widgets/dismissable_image.dart';
import 'package:unn_mobile/ui/widgets/packed_images_view.dart';

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: unn_mobile
description: A mobile application for UNN Portal website
publish_to: 'none'

version: 0.6.0+374
version: 0.6.0+375

environment:
sdk: '>=3.1.2 <4.0.0'
Expand Down