diff --git a/commitlint.yaml b/commitlint.yaml index d02e3a80a55..c4b7dcac914 100644 --- a/commitlint.yaml +++ b/commitlint.yaml @@ -22,6 +22,7 @@ rules: - neon_news - neon_notes - neon_notifications + - neon_talk - nextcloud - nextcloud_test - release diff --git a/packages/app/android/app/src/main/res/mipmap-hdpi/app_talk.png b/packages/app/android/app/src/main/res/mipmap-hdpi/app_talk.png new file mode 100644 index 00000000000..fdbda672402 Binary files /dev/null and b/packages/app/android/app/src/main/res/mipmap-hdpi/app_talk.png differ diff --git a/packages/app/android/app/src/main/res/mipmap-mdpi/app_talk.png b/packages/app/android/app/src/main/res/mipmap-mdpi/app_talk.png new file mode 100644 index 00000000000..ff2a5a88fc0 Binary files /dev/null and b/packages/app/android/app/src/main/res/mipmap-mdpi/app_talk.png differ diff --git a/packages/app/android/app/src/main/res/mipmap-xhdpi/app_talk.png b/packages/app/android/app/src/main/res/mipmap-xhdpi/app_talk.png new file mode 100644 index 00000000000..b40dd9bb870 Binary files /dev/null and b/packages/app/android/app/src/main/res/mipmap-xhdpi/app_talk.png differ diff --git a/packages/app/android/app/src/main/res/mipmap-xxhdpi/app_talk.png b/packages/app/android/app/src/main/res/mipmap-xxhdpi/app_talk.png new file mode 100644 index 00000000000..f1db86f9be6 Binary files /dev/null and b/packages/app/android/app/src/main/res/mipmap-xxhdpi/app_talk.png differ diff --git a/packages/app/android/app/src/main/res/mipmap-xxxhdpi/app_talk.png b/packages/app/android/app/src/main/res/mipmap-xxxhdpi/app_talk.png new file mode 100644 index 00000000000..aeca47d79f9 Binary files /dev/null and b/packages/app/android/app/src/main/res/mipmap-xxxhdpi/app_talk.png differ diff --git a/packages/app/lib/apps.dart b/packages/app/lib/apps.dart index fc07cf22c23..ecdf2f1704d 100644 --- a/packages/app/lib/apps.dart +++ b/packages/app/lib/apps.dart @@ -1,10 +1,12 @@ import 'package:built_collection/built_collection.dart'; +import 'package:flutter/foundation.dart'; import 'package:neon_dashboard/neon_dashboard.dart'; import 'package:neon_files/neon_files.dart'; import 'package:neon_framework/models.dart'; import 'package:neon_news/neon_news.dart'; import 'package:neon_notes/neon_notes.dart'; import 'package:neon_notifications/neon_notifications.dart'; +import 'package:neon_talk/neon_talk.dart'; /// The collection of clients enabled for the Neon app. final BuiltSet appImplementations = BuiltSet({ @@ -13,4 +15,5 @@ final BuiltSet appImplementations = BuiltSet({ NewsApp(), NotesApp(), NotificationsApp(), + if (kDebugMode) TalkApp(), }); diff --git a/packages/app/pubspec.lock b/packages/app/pubspec.lock index aca4bc4bf40..f4c19b6f72f 100644 --- a/packages/app/pubspec.lock +++ b/packages/app/pubspec.lock @@ -724,6 +724,13 @@ packages: relative: true source: path version: "1.0.0" + neon_talk: + dependency: "direct main" + description: + path: "../neon/neon_talk" + relative: true + source: path + version: "1.0.0" nested: dependency: transitive description: diff --git a/packages/app/pubspec.yaml b/packages/app/pubspec.yaml index 4f587c3b7f7..7560a42d2f8 100644 --- a/packages/app/pubspec.yaml +++ b/packages/app/pubspec.yaml @@ -34,6 +34,10 @@ dependencies: git: url: https://github.com/nextcloud/neon path: packages/neon/neon_notifications + neon_talk: + git: + url: https://github.com/nextcloud/neon + path: packages/neon/neon_talk vector_graphics: any dev_dependencies: diff --git a/packages/app/pubspec_overrides.yaml b/packages/app/pubspec_overrides.yaml index 7d35e8af507..1aa695758a3 100644 --- a/packages/app/pubspec_overrides.yaml +++ b/packages/app/pubspec_overrides.yaml @@ -1,4 +1,4 @@ -# melos_managed_dependency_overrides: dynamite_runtime,file_icons,neon_dashboard,neon_files,neon_framework,neon_lints,neon_news,neon_notes,neon_notifications,nextcloud,sort_box,package_info_plus +# melos_managed_dependency_overrides: dynamite_runtime,file_icons,neon_dashboard,neon_files,neon_framework,neon_lints,neon_news,neon_notes,neon_notifications,nextcloud,sort_box,package_info_plus,neon_talk dependency_overrides: dynamite_runtime: path: ../dynamite/dynamite_runtime @@ -27,3 +27,5 @@ dependency_overrides: url: https://github.com/fluttercommunity/plus_plugins ref: baa336fe79c29411542fc343d332846bcd7752c1 path: packages/package_info_plus/package_info_plus + neon_talk: + path: ../neon/neon_talk diff --git a/packages/neon/neon_talk/.metadata b/packages/neon/neon_talk/.metadata new file mode 100644 index 00000000000..9d75c7ec546 --- /dev/null +++ b/packages/neon/neon_talk/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "ead455963c12b453cdb2358cad34969c76daf180" + channel: "stable" + +project_type: package diff --git a/packages/neon/neon_talk/LICENSE b/packages/neon/neon_talk/LICENSE new file mode 120000 index 00000000000..c50ad9ade80 --- /dev/null +++ b/packages/neon/neon_talk/LICENSE @@ -0,0 +1 @@ +../../../assets/AGPL-3.0.txt \ No newline at end of file diff --git a/packages/neon/neon_talk/analysis_options.yaml b/packages/neon/neon_talk/analysis_options.yaml new file mode 100644 index 00000000000..66de1efdbdd --- /dev/null +++ b/packages/neon/neon_talk/analysis_options.yaml @@ -0,0 +1,5 @@ +include: package:neon_lints/flutter.yaml + +analyzer: + exclude: + - lib/l10n/** diff --git a/packages/neon/neon_talk/assets/app.svg.vec b/packages/neon/neon_talk/assets/app.svg.vec new file mode 100644 index 00000000000..5e441a9f6e8 Binary files /dev/null and b/packages/neon/neon_talk/assets/app.svg.vec differ diff --git a/packages/neon/neon_talk/build.yaml b/packages/neon/neon_talk/build.yaml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/neon/neon_talk/l10n.yaml b/packages/neon/neon_talk/l10n.yaml new file mode 100644 index 00000000000..5be45d90c54 --- /dev/null +++ b/packages/neon/neon_talk/l10n.yaml @@ -0,0 +1,7 @@ +arb-dir: lib/l10n +template-arb-file: en.arb +output-localization-file: localizations.dart +synthetic-package: false +output-class: TalkLocalizations +output-dir: lib/l10n +nullable-getter: false diff --git a/packages/neon/neon_talk/lib/l10n/en.arb b/packages/neon/neon_talk/lib/l10n/en.arb new file mode 100644 index 00000000000..7dc6d05dc6d --- /dev/null +++ b/packages/neon/neon_talk/lib/l10n/en.arb @@ -0,0 +1,3 @@ +{ + "@@locale": "en" +} diff --git a/packages/neon/neon_talk/lib/l10n/localizations.dart b/packages/neon/neon_talk/lib/l10n/localizations.dart new file mode 100644 index 00000000000..ef0da4204dd --- /dev/null +++ b/packages/neon/neon_talk/lib/l10n/localizations.dart @@ -0,0 +1,119 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:intl/intl.dart' as intl; + +import 'localizations_en.dart'; + +/// Callers can lookup localized strings with an instance of TalkLocalizations +/// returned by `TalkLocalizations.of(context)`. +/// +/// Applications need to include `TalkLocalizations.delegate()` in their app's +/// `localizationDelegates` list, and the locales they support in the app's +/// `supportedLocales` list. For example: +/// +/// ```dart +/// import 'l10n/localizations.dart'; +/// +/// return MaterialApp( +/// localizationsDelegates: TalkLocalizations.localizationsDelegates, +/// supportedLocales: TalkLocalizations.supportedLocales, +/// home: MyApplicationHome(), +/// ); +/// ``` +/// +/// ## Update pubspec.yaml +/// +/// Please make sure to update your pubspec.yaml to include the following +/// packages: +/// +/// ```yaml +/// dependencies: +/// # Internationalization support. +/// flutter_localizations: +/// sdk: flutter +/// intl: any # Use the pinned version from flutter_localizations +/// +/// # Rest of dependencies +/// ``` +/// +/// ## iOS Applications +/// +/// iOS applications define key application metadata, including supported +/// locales, in an Info.plist file that is built into the application bundle. +/// To configure the locales supported by your app, you’ll need to edit this +/// file. +/// +/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file. +/// Then, in the Project Navigator, open the Info.plist file under the Runner +/// project’s Runner folder. +/// +/// Next, select the Information Property List item, select Add Item from the +/// Editor menu, then select Localizations from the pop-up menu. +/// +/// Select and expand the newly-created Localizations item then, for each +/// locale your application supports, add a new item and select the locale +/// you wish to add from the pop-up menu in the Value field. This list should +/// be consistent with the languages listed in the TalkLocalizations.supportedLocales +/// property. +abstract class TalkLocalizations { + TalkLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString()); + + final String localeName; + + static TalkLocalizations of(BuildContext context) { + return Localizations.of(context, TalkLocalizations)!; + } + + static const LocalizationsDelegate delegate = _TalkLocalizationsDelegate(); + + /// A list of this localizations delegate along with the default localizations + /// delegates. + /// + /// Returns a list of localizations delegates containing this delegate along with + /// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, + /// and GlobalWidgetsLocalizations.delegate. + /// + /// Additional delegates can be added by appending to this list in + /// MaterialApp. This list does not have to be used at all if a custom list + /// of delegates is preferred or required. + static const List> localizationsDelegates = >[ + delegate, + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ]; + + /// A list of this localizations delegate's supported locales. + static const List supportedLocales = [Locale('en')]; +} + +class _TalkLocalizationsDelegate extends LocalizationsDelegate { + const _TalkLocalizationsDelegate(); + + @override + Future load(Locale locale) { + return SynchronousFuture(lookupTalkLocalizations(locale)); + } + + @override + bool isSupported(Locale locale) => ['en'].contains(locale.languageCode); + + @override + bool shouldReload(_TalkLocalizationsDelegate old) => false; +} + +TalkLocalizations lookupTalkLocalizations(Locale locale) { + // Lookup logic when only language code is specified. + switch (locale.languageCode) { + case 'en': + return TalkLocalizationsEn(); + } + + throw FlutterError('TalkLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.'); +} diff --git a/packages/neon/neon_talk/lib/l10n/localizations_en.dart b/packages/neon/neon_talk/lib/l10n/localizations_en.dart new file mode 100644 index 00000000000..a2a6c311caa --- /dev/null +++ b/packages/neon/neon_talk/lib/l10n/localizations_en.dart @@ -0,0 +1,6 @@ +import 'localizations.dart'; + +/// The translations for English (`en`). +class TalkLocalizationsEn extends TalkLocalizations { + TalkLocalizationsEn([String locale = 'en']) : super(locale); +} diff --git a/packages/neon/neon_talk/lib/neon_talk.dart b/packages/neon/neon_talk/lib/neon_talk.dart new file mode 100644 index 00000000000..48e2ee75d97 --- /dev/null +++ b/packages/neon/neon_talk/lib/neon_talk.dart @@ -0,0 +1,6 @@ +/// The Neon client for the Talk app. +/// +/// Add `TalkApp()` to your runNeon command to execute this app. +library neon_talk; + +export 'src/app.dart'; diff --git a/packages/neon/neon_talk/lib/src/app.dart b/packages/neon/neon_talk/lib/src/app.dart new file mode 100644 index 00000000000..49fe390618c --- /dev/null +++ b/packages/neon/neon_talk/lib/src/app.dart @@ -0,0 +1,42 @@ +import 'package:built_collection/built_collection.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; +import 'package:meta/meta.dart'; +import 'package:neon_framework/models.dart'; +import 'package:neon_talk/l10n/localizations.dart'; +import 'package:neon_talk/src/blocs/talk.dart'; +import 'package:neon_talk/src/options.dart'; +import 'package:neon_talk/src/pages/main.dart'; +import 'package:neon_talk/src/routes.dart'; +import 'package:nextcloud/nextcloud.dart'; + +/// Implementation of the server `talk` app. +@experimental +class TalkApp extends AppImplementation { + /// Creates a new Talk app implementation instance. + TalkApp(); + + @override + final String id = 'talk'; + + @override + final BuiltSet additionalMatchingIDs = BuiltSet([AppIDs.spreed]); + + @override + final LocalizationsDelegate localizationsDelegate = TalkLocalizations.delegate; + + @override + final List supportedLocales = TalkLocalizations.supportedLocales; + + @override + late final TalkOptions options = TalkOptions(storage); + + @override + TalkBloc buildBloc(Account account) => TalkBloc(account); + + @override + final Widget page = const TalkMainPage(); + + @override + final RouteBase route = $talkAppRoute; +} diff --git a/packages/neon/neon_talk/lib/src/blocs/talk.dart b/packages/neon/neon_talk/lib/src/blocs/talk.dart new file mode 100644 index 00000000000..410f0b877ae --- /dev/null +++ b/packages/neon/neon_talk/lib/src/blocs/talk.dart @@ -0,0 +1,19 @@ +import 'package:meta/meta.dart'; +import 'package:neon_framework/blocs.dart'; +import 'package:neon_framework/models.dart'; + +/// Bloc for fetching Talk rooms +sealed class TalkBloc implements InteractiveBloc { + /// Creates a new Talk Bloc instance. + @internal + factory TalkBloc(Account account) => _TalkBloc(account); +} + +class _TalkBloc extends InteractiveBloc implements TalkBloc { + _TalkBloc(this.account); + + final Account account; + + @override + Future refresh() async {} +} diff --git a/packages/neon/neon_talk/lib/src/options.dart b/packages/neon/neon_talk/lib/src/options.dart new file mode 100644 index 00000000000..fad7756dffb --- /dev/null +++ b/packages/neon/neon_talk/lib/src/options.dart @@ -0,0 +1,10 @@ +import 'package:neon_framework/settings.dart'; + +/// Settings options specific to the talk app. +class TalkOptions extends AppImplementationOptions { + /// Creates a new talk options instance. + TalkOptions(super.storage) { + super.categories = []; + super.options = []; + } +} diff --git a/packages/neon/neon_talk/lib/src/pages/main.dart b/packages/neon/neon_talk/lib/src/pages/main.dart new file mode 100644 index 00000000000..da60c8ea868 --- /dev/null +++ b/packages/neon/neon_talk/lib/src/pages/main.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +/// The main page displaying the chat list. +class TalkMainPage extends StatelessWidget { + /// Creates a new Talk main page. + const TalkMainPage({super.key}); + + @override + Widget build(BuildContext context) => const Placeholder(); +} diff --git a/packages/neon/neon_talk/lib/src/routes.dart b/packages/neon/neon_talk/lib/src/routes.dart new file mode 100644 index 00000000000..03b10929cc8 --- /dev/null +++ b/packages/neon/neon_talk/lib/src/routes.dart @@ -0,0 +1,20 @@ +import 'package:flutter/widgets.dart'; +import 'package:go_router/go_router.dart'; +import 'package:neon_framework/utils.dart'; +import 'package:neon_talk/src/pages/main.dart'; + +part 'routes.g.dart'; + +/// Route for the talk app. +@TypedGoRoute( + path: '${appsBaseRoutePrefix}talk', + name: 'talk', +) +@immutable +class TalkAppRoute extends NeonBaseAppRoute { + /// Creates a new talk app route. + const TalkAppRoute(); + + @override + Widget build(BuildContext context, GoRouterState state) => const TalkMainPage(); +} diff --git a/packages/neon/neon_talk/lib/src/routes.g.dart b/packages/neon/neon_talk/lib/src/routes.g.dart new file mode 100644 index 00000000000..c5b18f86dcf --- /dev/null +++ b/packages/neon/neon_talk/lib/src/routes.g.dart @@ -0,0 +1,33 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'routes.dart'; + +// ************************************************************************** +// GoRouterGenerator +// ************************************************************************** + +List get $appRoutes => [ + $talkAppRoute, + ]; + +RouteBase get $talkAppRoute => GoRouteData.$route( + path: '/apps/talk', + name: 'talk', + factory: $TalkAppRouteExtension._fromState, + ); + +extension $TalkAppRouteExtension on TalkAppRoute { + static TalkAppRoute _fromState(GoRouterState state) => const TalkAppRoute(); + + String get location => GoRouteData.$location( + '/apps/talk', + ); + + void go(BuildContext context) => context.go(location); + + Future push(BuildContext context) => context.push(location); + + void pushReplacement(BuildContext context) => context.pushReplacement(location); + + void replace(BuildContext context) => context.replace(location); +} diff --git a/packages/neon/neon_talk/pubspec.yaml b/packages/neon/neon_talk/pubspec.yaml new file mode 100644 index 00000000000..3205f0a4da9 --- /dev/null +++ b/packages/neon/neon_talk/pubspec.yaml @@ -0,0 +1,42 @@ +name: neon_talk +version: 1.0.0 +publish_to: 'none' + +environment: + sdk: '>=3.1.0 <4.0.0' + flutter: '>=3.13.0' + +dependencies: + built_collection: ^5.0.0 + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + go_router: ^13.0.0 + meta: ^1.0.0 + neon_framework: + git: + url: https://github.com/nextcloud/neon + path: packages/neon_framework + nextcloud: ^5.0.2 + +dev_dependencies: + build_runner: ^2.4.8 + go_router_builder: ^2.4.1 + neon_lints: + git: + url: https://github.com/nextcloud/neon + path: packages/neon_lints + vector_graphics_compiler: ^1.1.11+1 + +flutter: + uses-material-design: true + assets: + - assets/ + +dependency_overrides: + package_info_plus: + git: + url: https://github.com/fluttercommunity/plus_plugins + path: packages/package_info_plus/package_info_plus + ref: baa336fe79c29411542fc343d332846bcd7752c1 diff --git a/packages/neon/neon_talk/pubspec_overrides.yaml b/packages/neon/neon_talk/pubspec_overrides.yaml new file mode 100644 index 00000000000..07b9a0c4cb5 --- /dev/null +++ b/packages/neon/neon_talk/pubspec_overrides.yaml @@ -0,0 +1,17 @@ +# melos_managed_dependency_overrides: dynamite_runtime,neon_framework,neon_lints,nextcloud,sort_box,package_info_plus +dependency_overrides: + dynamite_runtime: + path: ../../dynamite/dynamite_runtime + neon_framework: + path: ../../neon_framework + neon_lints: + path: ../../neon_lints + nextcloud: + path: ../../nextcloud + sort_box: + path: ../../sort_box + package_info_plus: + git: + url: https://github.com/fluttercommunity/plus_plugins + ref: baa336fe79c29411542fc343d332846bcd7752c1 + path: packages/package_info_plus/package_info_plus diff --git a/packages/neon_framework/lib/l10n/en.arb b/packages/neon_framework/lib/l10n/en.arb index a7db74f0ea4..dd4d8ab2957 100644 --- a/packages/neon_framework/lib/l10n/en.arb +++ b/packages/neon_framework/lib/l10n/en.arb @@ -2,7 +2,7 @@ "@@locale": "en", "nextcloud": "Nextcloud", "nextcloudLogo": "Nextcloud logo", - "appImplementationName": "{app, select, nextcloud{Nextcloud} core{Server} dashboard{Dashboard} files{Files} news{News} notes{Notes} notifications{Notifications} other{}}", + "appImplementationName": "{app, select, nextcloud{Nextcloud} core{Server} dashboard{Dashboard} files{Files} news{News} notes{Notes} notifications{Notifications} talk{Talk} other{}}", "@appImplementationName": { "placeholders": { "app": {} diff --git a/packages/neon_framework/lib/l10n/localizations.dart b/packages/neon_framework/lib/l10n/localizations.dart index d2fd21809c9..98e85640291 100644 --- a/packages/neon_framework/lib/l10n/localizations.dart +++ b/packages/neon_framework/lib/l10n/localizations.dart @@ -104,7 +104,7 @@ abstract class NeonLocalizations { /// No description provided for @appImplementationName. /// /// In en, this message translates to: - /// **'{app, select, nextcloud{Nextcloud} core{Server} dashboard{Dashboard} files{Files} news{News} notes{Notes} notifications{Notifications} other{}}'** + /// **'{app, select, nextcloud{Nextcloud} core{Server} dashboard{Dashboard} files{Files} news{News} notes{Notes} notifications{Notifications} talk{Talk} other{}}'** String appImplementationName(String app); /// No description provided for @loginAgain. diff --git a/packages/neon_framework/lib/l10n/localizations_en.dart b/packages/neon_framework/lib/l10n/localizations_en.dart index 68ccb089549..85dc61735d9 100644 --- a/packages/neon_framework/lib/l10n/localizations_en.dart +++ b/packages/neon_framework/lib/l10n/localizations_en.dart @@ -24,6 +24,7 @@ class NeonLocalizationsEn extends NeonLocalizations { 'news': 'News', 'notes': 'Notes', 'notifications': 'Notifications', + 'talk': 'Talk', 'other': '', }, ); diff --git a/tool/generate-assets.sh b/tool/generate-assets.sh index 7f7015f3076..ba33cde7a9e 100755 --- a/tool/generate-assets.sh +++ b/tool/generate-assets.sh @@ -80,6 +80,7 @@ copy_app_svg files external/nextcloud-server/apps/files copy_app_svg news external/nextcloud-news copy_app_svg notes external/nextcloud-notes copy_app_svg notifications external/nextcloud-notifications +copy_app_svg talk external/nextcloud-spreed ( cd packages/app