Skip to content

Commit

Permalink
feat: AI chat (#5383)
Browse files Browse the repository at this point in the history
* chore: ai type

* chore: use patch to fix version issue

* chore: update

* chore: update

* chore: integrate client api

* chore: add schema

* chore: setup event

* chore: add event test

* chore: add test

* chore: update test

* chore: load chat message

* chore: load chat message

* chore: chat ui

* chore: disable create chat

* chore: update client api

* chore: disable chat

* chore: ui theme

* chore: ui theme

* chore: copy message

* chore: fix test

* chore: show error

* chore: update bloc

* chore: update test

* chore: lint

* chore: icon

* chore: hover

* chore: show unsupported page

* chore: adjust mobile ui

* chore: adjust view title bar

* chore: return related question

* chore: error page

* chore: error page

* chore: code format

* chore: prompt

* chore: fix test

* chore: ui adjust

* chore: disable create chat

* chore: add loading page

* chore: fix test

* chore: disable chat action

* chore: add maximum text limit
  • Loading branch information
appflowy authored Jun 3, 2024
1 parent 4d42c9e commit aec7bc8
Show file tree
Hide file tree
Showing 114 changed files with 5,473 additions and 282 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/flutter_ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ jobs:
with:
os: ${{ matrix.os }}
flutter_version: ${{ env.FLUTTER_VERSION }}
DISABLE_CI_TEST_LOG: "true"
rust_toolchain: ${{ env.RUST_TOOLCHAIN }}
cargo_make_version: ${{ env.CARGO_MAKE_VERSION }}
rust_target: ${{ matrix.target }}
Expand Down Expand Up @@ -202,6 +203,7 @@ jobs:
- name: Run Flutter unit tests
env:
DISABLE_EVENT_LOG: true
DISABLE_CI_TEST_LOG: "true"
working-directory: frontend
run: |
if [ "$RUNNER_OS" == "macOS" ]; then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ void main() {

// create document, board, grid and calendar views
for (final value in ViewLayoutPB.values) {
if (value == ViewLayoutPB.Chat) {
continue;
}
await tester.createNewPageWithNameUnderParent(
name: value.name,
parentName: gettingStarted,
Expand Down Expand Up @@ -46,6 +49,9 @@ void main() {

// create document, board, grid and calendar views
for (final value in ViewLayoutPB.values) {
if (value == ViewLayoutPB.Chat) {
continue;
}
await tester.createNewPageWithNameUnderParent(
name: value.name,
parentName: gettingStarted,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ void main() {
await tester.tapAnonymousSignInButton();

for (final layout in ViewLayoutPB.values) {
if (layout == ViewLayoutPB.Chat) {
continue;
}
// create a new page
final name = 'AppFlowy_$layout';
await tester.createNewPageWithNameUnderParent(
Expand Down Expand Up @@ -66,6 +69,8 @@ void main() {
case ViewLayoutPB.Calendar:
expect(find.byType(CalendarPage), findsOneWidget);
break;
case ViewLayoutPB.Chat:
break;
}

await tester.openPage(gettingStarted);
Expand Down
4 changes: 2 additions & 2 deletions frontend/appflowy_flutter/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ SPEC CHECKSUMS:
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
flowy_infra_ui: 0455e1fa8c51885aa1437848e361e99419f34ebc
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
fluttertoast: 31b00dabfa7fb7bacd9e7dbee580d7a2ff4bf265
fluttertoast: fafc4fa4d01a6a9e4f772ecd190ffa525e9e2d9c
image_gallery_saver: cb43cc43141711190510e92c460eb1655cd343cb
image_picker_ios: 99dfe1854b4fa34d0364e74a78448a0151025425
integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4
Expand All @@ -227,4 +227,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: d0d9b4ff572d8695c38eb3f9b490f55cdfc57eca

COCOAPODS: 1.15.2
COCOAPODS: 1.11.3
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import 'dart:async';
import 'dart:convert';

import 'package:appflowy/mobile/presentation/chat/mobile_chat_screen.dart';
import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart';
import 'package:flutter/material.dart';

import 'package:appflowy/mobile/presentation/database/board/mobile_board_screen.dart';
import 'package:appflowy/mobile/presentation/database/mobile_calendar_screen.dart';
import 'package:appflowy/mobile/presentation/database/mobile_grid_screen.dart';
import 'package:appflowy/mobile/presentation/presentation.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/workspace/application/recent/cached_recent_service.dart';
import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

extension MobileRouter on BuildContext {
Expand Down Expand Up @@ -37,6 +39,9 @@ extension on ViewPB {
return MobileCalendarScreen.routeName;
case ViewLayoutPB.Board:
return MobileBoardScreen.routeName;
case ViewLayoutPB.Chat:
return MobileChatScreen.routeName;

default:
throw UnimplementedError('routeName for $this is not implemented');
}
Expand Down Expand Up @@ -65,6 +70,11 @@ extension on ViewPB {
MobileBoardScreen.viewId: id,
MobileBoardScreen.viewTitle: name,
};
case ViewLayoutPB.Chat:
return {
MobileChatScreen.viewId: id,
MobileChatScreen.viewTitle: name,
};
default:
throw UnimplementedError(
'queryParameters for $this is not implemented',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:appflowy/plugins/base/emoji/emoji_text.dart';
import 'package:appflowy/plugins/document/presentation/document_collaborators.dart';
import 'package:appflowy/plugins/shared/sync_indicator.dart';
import 'package:appflowy/shared/feature_flags.dart';
import 'package:appflowy/startup/plugin/plugin.dart';
import 'package:appflowy/startup/startup.dart';
import 'package:appflowy/user/application/reminder/reminder_bloc.dart';
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
Expand Down Expand Up @@ -154,7 +155,10 @@ class _MobileViewPageState extends State<MobileViewPage> {
(view) {
final plugin = view.plugin(arguments: widget.arguments ?? const {})
..init();
return plugin.widgetBuilder.buildWidget(shrinkWrap: false);
return plugin.widgetBuilder.buildWidget(
shrinkWrap: false,
context: PluginContext(userProfile: state.userProfilePB),
);
},
(error) {
return FlowyMobileStateContainer.error(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'package:appflowy/mobile/presentation/base/mobile_view_page.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:flutter/material.dart';

class MobileChatScreen extends StatelessWidget {
const MobileChatScreen({
super.key,
required this.id,
this.title,
});

/// view id
final String id;
final String? title;

static const routeName = '/chat';
static const viewId = 'id';
static const viewTitle = 'title';

@override
Widget build(BuildContext context) {
return MobileViewPage(
id: id,
title: title,
viewLayout: ViewLayoutPB.Chat,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:appflowy_backend/protobuf/flowy-document/protobuf.dart';
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_chat_types/flutter_chat_types.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part 'chat_ai_message_bloc.freezed.dart';

class ChatAIMessageBloc extends Bloc<ChatAIMessageEvent, ChatAIMessageState> {
ChatAIMessageBloc({
required Message message,
}) : super(ChatAIMessageState.initial(message)) {
on<ChatAIMessageEvent>(
(event, emit) async {
await event.when(
initial: () async {},
update: (userProfile, deviceId, states) {},
);
},
);
}
}

@freezed
class ChatAIMessageEvent with _$ChatAIMessageEvent {
const factory ChatAIMessageEvent.initial() = Initial;
const factory ChatAIMessageEvent.update(
UserProfilePB userProfile,
String deviceId,
DocumentAwarenessStatesPB states,
) = Update;
}

@freezed
class ChatAIMessageState with _$ChatAIMessageState {
const factory ChatAIMessageState({
required Message message,
}) = _ChatAIMessageState;

factory ChatAIMessageState.initial(Message message) =>
ChatAIMessageState(message: message);
}
Loading

0 comments on commit aec7bc8

Please sign in to comment.