├── lib
├── pages
│ ├── drive
│ │ ├── drive_info.dart
│ │ └── drive_page.dart
│ ├── user_widgets
│ │ └── widgets_list
│ │ │ ├── state.dart
│ │ │ └── view.dart
│ ├── settings
│ │ ├── test
│ │ │ └── test_page.dart
│ │ ├── router.dart
│ │ ├── member_info_state.dart
│ │ └── two_panel_layout.dart
│ ├── timeline
│ │ └── timeline_list.dart
│ ├── notifications
│ │ └── notifications_mentions_list.dart
│ ├── users
│ │ └── user_reactions_list.dart
│ ├── search
│ │ └── search_page.dart
│ ├── splash_page
│ │ └── splash_page.dart
│ ├── clips
│ │ ├── clips.dart
│ │ ├── clips_collection.dart
│ │ └── clips_my.dart
│ ├── hashtag
│ │ └── hashtag_page.dart
│ ├── home
│ │ └── home_page_state.dart
│ └── explore
│ │ └── explore.dart
├── widgets
│ ├── mk_load_more.dart
│ ├── sliver_presistent_header.dart
│ ├── mk_dialog.dart
│ ├── driver
│ │ └── driver_select_dialog
│ │ │ └── driver_select_dialog_state.dart
│ ├── blur_widget.dart
│ ├── login
│ │ ├── servers_select_state.dart
│ │ └── login_dialog.dart
│ ├── mk_switch.dart
│ ├── hashtag
│ │ └── hashtag_select_dialog_state.dart
│ ├── keep_alive_wrapper.dart
│ ├── mk_refresh_loading_empty_wrapper.dart
│ ├── mk_card.dart
│ ├── mk_scaffold.dart
│ ├── mfm_text
│ │ └── animate
│ │ │ ├── spin.dart
│ │ │ └── jelly.dart
│ ├── hover_builder.dart
│ ├── mk_nav_button.dart
│ ├── mk_button.dart
│ ├── user_select_dialog
│ │ └── user_select_dialog_state.dart
│ ├── sliver_load_more.dart
│ └── clips
│ │ └── clips_create_dialog_state.dart
├── logger.dart
├── apis
│ ├── services
│ │ ├── services.dart
│ │ ├── hashtags_service.dart
│ │ ├── following_service.dart
│ │ ├── auth_service.dart
│ │ ├── account_service.dart
│ │ ├── app_service.dart
│ │ └── meta_service.dart
│ ├── models
│ │ ├── auth.dart
│ │ ├── translate.dart
│ │ ├── app.dart
│ │ ├── login_user.dart
│ │ ├── following.dart
│ │ ├── emojis.dart
│ │ ├── clips.dart
│ │ ├── announcement.dart
│ │ ├── drive.dart
│ │ ├── user_full.dart
│ │ └── user_lite.dart
│ ├── dio.dart
│ └── index.dart
├── utils
│ ├── get_token.dart
│ ├── time_to_desired_format.dart
│ ├── get_random_string.dart
│ ├── get_padding_note.dart
│ ├── image_compression.dart
│ ├── custom_rect_tween.dart
│ ├── time_ago_since_date.dart
│ ├── format_duration.dart
│ ├── update_themes.dart
│ └── save_image.dart
├── status
│ ├── global_snackbar.dart
│ ├── me_detailed.dart
│ ├── mk_tabbar_refresh_scroll_state.dart
│ ├── misskey_api.dart
│ ├── dio.dart
│ ├── timeline.dart
│ ├── notifications.dart
│ └── user_login.dart
├── database
│ ├── link_preview.dart
│ ├── notes.dart
│ ├── users.dart
│ ├── timeline.dart
│ ├── instance.dart
│ └── init_database.dart
└── hook
│ ├── use_mk_refresh_load_list_controller.dart
│ ├── useTimelineScrollController.dart
│ └── useExtendedPageController.dart
├── linux
├── .gitignore
├── main.cc
├── flutter
│ ├── generated_plugin_registrant.h
│ ├── generated_plugins.cmake
│ └── generated_plugin_registrant.cc
└── my_application.h
├── .roo
└── mcp.json
├── ios
├── Runner
│ ├── Runner-Bridging-Header.h
│ ├── Assets.xcassets
│ │ ├── LaunchImage.imageset
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ ├── README.md
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-50x50@1x.png
│ │ │ ├── Icon-App-50x50@2x.png
│ │ │ ├── Icon-App-57x57@1x.png
│ │ │ ├── Icon-App-57x57@2x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-72x72@1x.png
│ │ │ ├── Icon-App-72x72@2x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-83.5x83.5@2x.png
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ └── Info.plist
├── Flutter
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── AppFrameworkInfo.plist
├── Runner.xcodeproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ ├── WorkspaceSettings.xcsettings
│ │ └── IDEWorkspaceChecks.plist
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── WorkspaceSettings.xcsettings
│ │ └── IDEWorkspaceChecks.plist
├── ExportOptions.plist
├── RunnerTests
│ └── RunnerTests.swift
├── .gitignore
└── Podfile
├── docs
├── Moekey.png
├── banner.png
└── Screenshot.png
├── assets
├── favicon.ico
├── favicon.png
├── misskey.png
├── favicon.icns
└── android_icon
│ └── ic_launcher_background.svg
├── .editorconfig
├── android
├── gradle.properties
├── app
│ ├── src
│ │ ├── main
│ │ │ ├── ic_launcher-playstore.png
│ │ │ ├── res
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── values
│ │ │ │ │ ├── colors.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── mipmap-anydpi-v26
│ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ ├── drawable
│ │ │ │ │ ├── launch_background.xml
│ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ │ ├── drawable-v21
│ │ │ │ │ └── launch_background.xml
│ │ │ │ ├── drawable-v24
│ │ │ │ │ └── ic_launcher_background.xml
│ │ │ │ └── values-night
│ │ │ │ │ └── styles.xml
│ │ │ ├── kotlin
│ │ │ │ └── love
│ │ │ │ │ └── moegirl
│ │ │ │ │ └── moekey
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── AndroidManifest.xml
│ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ └── profile
│ │ │ └── AndroidManifest.xml
│ └── build.gradle
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── .gitignore
├── build.gradle
└── settings.gradle
├── macos
├── Runner
│ ├── Configs
│ │ ├── Debug.xcconfig
│ │ ├── Release.xcconfig
│ │ ├── Warnings.xcconfig
│ │ └── AppInfo.xcconfig
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ ├── app_icon_16.png
│ │ │ ├── app_icon_32.png
│ │ │ ├── app_icon_64.png
│ │ │ ├── app_icon_1024.png
│ │ │ ├── app_icon_128.png
│ │ │ ├── app_icon_256.png
│ │ │ ├── app_icon_512.png
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── Release.entitlements
│ ├── MainFlutterWindow.swift
│ ├── DebugProfile.entitlements
│ └── Info.plist
├── .gitignore
├── Flutter
│ ├── Flutter-Debug.xcconfig
│ ├── Flutter-Release.xcconfig
│ └── GeneratedPluginRegistrant.swift
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── Runner.xcodeproj
│ └── project.xcworkspace
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── RunnerTests
│ └── RunnerTests.swift
└── Podfile
├── windows
├── runner
│ ├── resources
│ │ └── app_icon.ico
│ ├── resource.h
│ ├── utils.h
│ ├── runner.exe.manifest
│ ├── flutter_window.h
│ ├── main.cpp
│ ├── CMakeLists.txt
│ ├── utils.cpp
│ └── flutter_window.cpp
├── .gitignore
└── flutter
│ ├── generated_plugin_registrant.h
│ ├── generated_plugins.cmake
│ └── generated_plugin_registrant.cc
├── devtools_options.yaml
├── crowdin.yml
├── .vscode
├── settings.json
├── tasks.json
└── launch.json
├── .gitignore
├── .clineignore
├── README.zh_CN.md
├── test
└── widget_test.dart
├── README.md
├── .metadata
└── analysis_options.yaml
/lib/pages/drive/drive_info.dart:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/lib/widgets/mk_load_more.dart:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/linux/.gitignore:
--------------------------------------------------------------------------------
1 | flutter/ephemeral
2 |
--------------------------------------------------------------------------------
/.roo/mcp.json:
--------------------------------------------------------------------------------
1 | {
2 | "mcpServers": {}
3 | }
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/docs/Moekey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/docs/Moekey.png
--------------------------------------------------------------------------------
/docs/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/docs/banner.png
--------------------------------------------------------------------------------
/assets/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/assets/favicon.ico
--------------------------------------------------------------------------------
/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/assets/favicon.png
--------------------------------------------------------------------------------
/assets/misskey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/assets/misskey.png
--------------------------------------------------------------------------------
/lib/logger.dart:
--------------------------------------------------------------------------------
1 | import 'package:logger/logger.dart';
2 |
3 | var logger = Logger();
4 |
--------------------------------------------------------------------------------
/assets/favicon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/assets/favicon.icns
--------------------------------------------------------------------------------
/docs/Screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/docs/Screenshot.png
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*.dart]
4 | charset = utf-8
5 | end_of_line = lf
6 | insert_final_newline = true
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx4G
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Debug.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Release.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/windows/runner/resources/app_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/windows/runner/resources/app_icon.ico
--------------------------------------------------------------------------------
/macos/.gitignore:
--------------------------------------------------------------------------------
1 | # Flutter-related
2 | **/Flutter/ephemeral/
3 | **/Pods/
4 |
5 | # Xcode-related
6 | **/dgph
7 | **/xcuserdata/
8 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/android/app/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/android/app/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/lib/pages/user_widgets/widgets_list/state.dart:
--------------------------------------------------------------------------------
1 | class WidgetsListState {
2 | WidgetsListState() {
3 | ///Initialize variables
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/macos/Flutter/Flutter-Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "ephemeral/Flutter-Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/macos/Flutter/Flutter-Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "ephemeral/Flutter-Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #E9AFC6
4 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
--------------------------------------------------------------------------------
/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MoeKeyDev/MoeKey/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/love/moegirl/moekey/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package love.moegirl.moekey
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/devtools_options.yaml:
--------------------------------------------------------------------------------
1 | description: This file stores settings for Dart & Flutter DevTools.
2 | documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
3 | extensions:
4 |
--------------------------------------------------------------------------------
/lib/apis/services/services.dart:
--------------------------------------------------------------------------------
1 | import 'package:moekey/apis/dio.dart';
2 |
3 | abstract class MisskeyApiServices {
4 | MisskeyApiServices({required this.client});
5 |
6 | MisskeyApisHttpClient client;
7 | }
8 |
--------------------------------------------------------------------------------
/linux/main.cc:
--------------------------------------------------------------------------------
1 | #include "my_application.h"
2 |
3 | int main(int argc, char** argv) {
4 | g_autoptr(MyApplication) app = my_application_new();
5 | return g_application_run(G_APPLICATION(app), argc, argv);
6 | }
7 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
6 |
--------------------------------------------------------------------------------
/macos/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | @NSApplicationMain
5 | class AppDelegate: FlutterAppDelegate {
6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
7 | return true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lib/utils/get_token.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:crypto/crypto.dart';
4 |
5 | String getToken(String accessToken, String appSecret) {
6 | final bytes = utf8.encode(accessToken + appSecret);
7 | final hash = sha256.convert(bytes);
8 | return hash.toString();
9 | }
10 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/macos/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/ExportOptions.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | method
6 | ad-hoc
7 | compileBitcode
8 |
9 |
10 |
--------------------------------------------------------------------------------
/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/crowdin.yml:
--------------------------------------------------------------------------------
1 | project_id_env: CROWDIN_PROJECT_ID
2 | api_token_env: CROWDIN_KEY
3 | base_path: .
4 | base_url: 'https://api.crowdin.com'
5 | preserve_hierarchy: 1
6 | files:
7 | - source: /lib/l10n/intl_zh_CN.arb
8 | translation: /%original_path%/intl_%locale_with_underscore%.arb
9 | type: arb
10 | update_option: update_as_unapproved
11 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/lib/utils/time_to_desired_format.dart:
--------------------------------------------------------------------------------
1 | import 'package:intl/intl.dart';
2 | import 'package:moekey/utils/time_ago_since_date.dart';
3 |
4 | String timeToDesiredFormat(DateTime dateTime) {
5 | String formattedDateTime =
6 | DateFormat('yyyy/MM/dd HH:mm:ss').format(dateTime.toLocal());
7 | return "$formattedDateTime (${timeAgoSinceDate(dateTime)})";
8 | }
9 |
--------------------------------------------------------------------------------
/ios/RunnerTests/RunnerTests.swift:
--------------------------------------------------------------------------------
1 | import Flutter
2 | import UIKit
3 | import XCTest
4 |
5 | class RunnerTests: XCTestCase {
6 |
7 | func testExample() {
8 | // If you add code to the Runner application, consider adding tests here.
9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/lib/utils/get_random_string.dart:
--------------------------------------------------------------------------------
1 | import 'dart:math';
2 |
3 | String getRandomString(int length) {
4 | const characters =
5 | '+-*=?AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz';
6 | Random random = Random();
7 | return String.fromCharCodes(Iterable.generate(
8 | length, (_) => characters.codeUnitAt(random.nextInt(characters.length))));
9 | }
10 |
--------------------------------------------------------------------------------
/macos/RunnerTests/RunnerTests.swift:
--------------------------------------------------------------------------------
1 | import FlutterMacOS
2 | import Cocoa
3 | import XCTest
4 |
5 | class RunnerTests: XCTestCase {
6 |
7 | func testExample() {
8 | // If you add code to the Runner application, consider adding tests here.
9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/windows/.gitignore:
--------------------------------------------------------------------------------
1 | flutter/ephemeral/
2 |
3 | # Visual Studio user-specific files.
4 | *.suo
5 | *.user
6 | *.userosscache
7 | *.sln.docstates
8 |
9 | # Visual Studio build-related files.
10 | x64/
11 | x86/
12 |
13 | # Visual Studio cache files
14 | # files ending in .cache can be ignored
15 | *.[Cc]ache
16 | # but keep track of directories ending in .cache
17 | !*.[Cc]ache/
18 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/lib/utils/get_padding_note.dart:
--------------------------------------------------------------------------------
1 | double getPaddingForNote(constraints) {
2 | double padding = 0;
3 | if (constraints.maxWidth > 860) {
4 | padding = (constraints.maxWidth - 800) / 2;
5 | } else if (constraints.maxWidth > 500) {
6 | padding = 30;
7 | } else if (constraints.maxWidth > 400) {
8 | padding = 8;
9 | } else {
10 | padding = 0;
11 | }
12 | return padding;
13 | }
14 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.exclude": {
3 | "**/*.freezed.dart": true,
4 | "**/*.g.dart": true
5 | },
6 | "emeraldwalk.runonsave": {
7 | "commands": [
8 | {
9 | "match": "\\.arb$",
10 | "isAsync": true,
11 | "cmd": "flutter pub global run intl_utils:generate"
12 | }
13 | ]
14 | }
15 | }
--------------------------------------------------------------------------------
/linux/flutter/generated_plugin_registrant.h:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | // clang-format off
6 |
7 | #ifndef GENERATED_PLUGIN_REGISTRANT_
8 | #define GENERATED_PLUGIN_REGISTRANT_
9 |
10 | #include
11 |
12 | // Registers Flutter plugins.
13 | void fl_register_plugins(FlPluginRegistry* registry);
14 |
15 | #endif // GENERATED_PLUGIN_REGISTRANT_
16 |
--------------------------------------------------------------------------------
/windows/flutter/generated_plugin_registrant.h:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | // clang-format off
6 |
7 | #ifndef GENERATED_PLUGIN_REGISTRANT_
8 | #define GENERATED_PLUGIN_REGISTRANT_
9 |
10 | #include
11 |
12 | // Registers Flutter plugins.
13 | void RegisterPlugins(flutter::PluginRegistry* registry);
14 |
15 | #endif // GENERATED_PLUGIN_REGISTRANT_
16 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/macos/Runner/Release.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.network.client
8 |
9 | com.apple.security.network.server
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/lib/utils/image_compression.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:image_compression/image_compression.dart';
4 |
5 | Future imageCompression(String path) async {
6 | final file = File(path);
7 |
8 | final input = ImageFile(
9 | rawBytes: file.readAsBytesSync(),
10 | filePath: file.path,
11 | );
12 | final output = await compressInQueue(ImageFileConfiguration(input: input));
13 | return output;
14 | }
15 |
--------------------------------------------------------------------------------
/lib/pages/drive/drive_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:hooks_riverpod/hooks_riverpod.dart';
3 |
4 | import '../../widgets/driver/driver_list.dart';
5 |
6 | class DrivePage extends HookConsumerWidget {
7 | const DrivePage({super.key});
8 |
9 | @override
10 | Widget build(BuildContext context, WidgetRef ref) {
11 | return const Scaffold(
12 | body: DriverList(),
13 | );
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/lib/apis/services/hashtags_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:moekey/apis/services/services.dart';
2 |
3 | class HashtagsService extends MisskeyApiServices {
4 | HashtagsService({required super.client});
5 |
6 | search({String? query}) async {
7 | var list = await client
8 | .post("/hashtags/search", data: {"query": query, "limit": 30});
9 | return List.from(list.map(
10 | (e) => e,
11 | ));
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "label": "Generate Intl",
6 | "type": "shell",
7 | "command": "flutter pub global run intl_utils:generate",
8 | "problemMatcher": [],
9 | "presentation": {
10 | "reveal": "always",
11 | "panel": "new"
12 | },
13 | "group": "build"
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/lib/status/global_snackbar.dart:
--------------------------------------------------------------------------------
1 | import 'package:riverpod_annotation/riverpod_annotation.dart';
2 |
3 | part 'global_snackbar.g.dart';
4 |
5 | @riverpod
6 | class GlobalSnackbar extends _$GlobalSnackbar {
7 | @override
8 | String? build() {
9 | return null;
10 | }
11 |
12 | show(String message) {
13 | state = message;
14 | // 触发监听器
15 | ref.notifyListeners();
16 | }
17 |
18 | hide() {
19 | state = null;
20 | ref.notifyListeners();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/linux/my_application.h:
--------------------------------------------------------------------------------
1 | #ifndef FLUTTER_MY_APPLICATION_H_
2 | #define FLUTTER_MY_APPLICATION_H_
3 |
4 | #include
5 |
6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
7 | GtkApplication)
8 |
9 | /**
10 | * my_application_new:
11 | *
12 | * Creates a new Flutter-based application.
13 | *
14 | * Returns: a new #MyApplication.
15 | */
16 | MyApplication* my_application_new();
17 |
18 | #endif // FLUTTER_MY_APPLICATION_H_
19 |
--------------------------------------------------------------------------------
/macos/Runner/MainFlutterWindow.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | class MainFlutterWindow: NSWindow {
5 | override func awakeFromNib() {
6 | let flutterViewController = FlutterViewController()
7 | let windowFrame = self.frame
8 | self.contentViewController = flutterViewController
9 | self.setFrame(windowFrame, display: true)
10 |
11 | RegisterGeneratedPlugins(registry: flutterViewController)
12 |
13 | super.awakeFromNib()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/macos/Runner/DebugProfile.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.cs.allow-jit
8 |
9 | com.apple.security.network.client
10 |
11 | com.apple.security.network.server
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/lib/status/me_detailed.dart:
--------------------------------------------------------------------------------
1 | import 'package:moekey/status/misskey_api.dart';
2 | import 'package:riverpod_annotation/riverpod_annotation.dart';
3 |
4 | import '../apis/models/me_detailed.dart';
5 |
6 | part 'me_detailed.g.dart';
7 |
8 | @Riverpod(keepAlive: true)
9 | class CurrentMeDetailed extends _$CurrentMeDetailed {
10 | @override
11 | FutureOr build() async {
12 | var api = ref.watch(misskeyApisProvider);
13 | var info = await api.account.i();
14 | return info;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/windows/runner/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by Runner.rc
4 | //
5 | #define IDI_APP_ICON 101
6 |
7 | // Next default values for new objects
8 | //
9 | #ifdef APSTUDIO_INVOKED
10 | #ifndef APSTUDIO_READONLY_SYMBOLS
11 | #define _APS_NEXT_RESOURCE_VALUE 102
12 | #define _APS_NEXT_COMMAND_VALUE 40001
13 | #define _APS_NEXT_CONTROL_VALUE 1001
14 | #define _APS_NEXT_SYMED_VALUE 101
15 | #endif
16 | #endif
17 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/lib/status/mk_tabbar_refresh_scroll_state.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:hooks_riverpod/hooks_riverpod.dart';
3 | import 'package:riverpod_annotation/riverpod_annotation.dart';
4 |
5 | import '../widgets/mk_tabbar_list.dart';
6 |
7 | part 'mk_tabbar_refresh_scroll_state.g.dart';
8 |
9 | @Riverpod(keepAlive: true)
10 | GlobalKey mkTabBarRefreshScrollStatus(
11 | Ref ref, String label) {
12 | return GlobalKey(debugLabel: label);
13 | }
14 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/apis/models/auth.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 | import 'package:flutter/foundation.dart';
3 |
4 | part 'auth.freezed.dart';
5 |
6 | part 'auth.g.dart';
7 |
8 | @freezed
9 | abstract class SessionGenerateModel with _$SessionGenerateModel {
10 | const factory SessionGenerateModel({
11 | required String token,
12 | required String url,
13 | }) = _SessionGenerateModel;
14 |
15 | factory SessionGenerateModel.fromJson(Map json) =>
16 | _$SessionGenerateModelFromJson(json);
17 | }
18 |
--------------------------------------------------------------------------------
/lib/apis/models/translate.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 | import 'package:flutter/foundation.dart';
3 |
4 | part 'translate.freezed.dart';
5 |
6 | part 'translate.g.dart';
7 |
8 | @unfreezed
9 | abstract class NoteTranslate with _$NoteTranslate {
10 | factory NoteTranslate({
11 | required String sourceLang,
12 | required String text,
13 | @Default(true) bool loading,
14 | }) = _NoteTranslate;
15 |
16 | factory NoteTranslate.fromJson(Map json) =>
17 | _$NoteTranslateFromJson(json);
18 | }
19 |
--------------------------------------------------------------------------------
/lib/apis/models/app.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 | import 'package:flutter/foundation.dart';
3 |
4 | part 'app.freezed.dart';
5 |
6 | part 'app.g.dart';
7 |
8 | @freezed
9 | abstract class AppModel with _$AppModel {
10 | const factory AppModel({
11 | String? callbackUrl,
12 | required String id,
13 | bool? isAuthorized,
14 | required String name,
15 | required List permission,
16 | String? secret,
17 | }) = _AppModel;
18 |
19 | factory AppModel.fromJson(Map json) =>
20 | _$AppModelFromJson(json);
21 | }
22 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/Warnings.xcconfig:
--------------------------------------------------------------------------------
1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
2 | GCC_WARN_UNDECLARED_SELECTOR = YES
3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
6 | CLANG_WARN_PRAGMA_PACK = YES
7 | CLANG_WARN_STRICT_PROTOTYPES = YES
8 | CLANG_WARN_COMMA = YES
9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES
10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
12 | GCC_WARN_SHADOW = YES
13 | CLANG_WARN_UNREACHABLE_CODE = YES
14 |
--------------------------------------------------------------------------------
/lib/apis/models/login_user.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 | import 'package:moekey/apis/models/user_full.dart';
3 | import 'package:flutter/foundation.dart';
4 |
5 | part 'login_user.freezed.dart';
6 |
7 | part 'login_user.g.dart';
8 |
9 | @freezed
10 | abstract class LoginUser with _$LoginUser {
11 | const factory LoginUser({
12 | required String serverUrl,
13 | required String token,
14 | required UserFullModel userInfo,
15 | required String name,
16 | required String id,
17 | }) = _LoginUser;
18 |
19 | factory LoginUser.fromJson(Map json) =>
20 | _$LoginUserFromJson(json);
21 | }
22 |
--------------------------------------------------------------------------------
/lib/widgets/sliver_presistent_header.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class HeaderDelegate extends SliverPersistentHeaderDelegate {
4 | const HeaderDelegate({required this.child, this.extent = 50});
5 |
6 | final Widget child;
7 | final double extent;
8 |
9 | @override
10 | Widget build(
11 | BuildContext context, double shrinkOffset, bool overlapsContent) {
12 | return child;
13 | }
14 |
15 | @override
16 | double get maxExtent => extent;
17 |
18 | @override
19 | double get minExtent => extent;
20 |
21 | @override
22 | bool shouldRebuild(covariant HeaderDelegate oldDelegate) =>
23 | child != oldDelegate.child;
24 | }
25 |
--------------------------------------------------------------------------------
/macos/Runner/Configs/AppInfo.xcconfig:
--------------------------------------------------------------------------------
1 | // Application-level settings for the Runner target.
2 | //
3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
4 | // future. If not, the values below would default to using the project name when this becomes a
5 | // 'flutter create' template.
6 |
7 | // The application's name. By default this is also the title of the Flutter window.
8 | PRODUCT_NAME = MoeKey
9 |
10 | // The application's bundle identifier
11 | PRODUCT_BUNDLE_IDENTIFIER = love.moegirl.moekey
12 |
13 | // The copyright displayed in application information
14 | PRODUCT_COPYRIGHT = Copyright © 2024 love.moegirl. All rights reserved.
15 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.9.22'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
10 | }
11 | }
12 |
13 | allprojects {
14 | repositories {
15 | google()
16 | mavenCentral()
17 | }
18 | }
19 |
20 | rootProject.buildDir = '../build'
21 | subprojects {
22 | project.buildDir = "${rootProject.buildDir}/${project.name}"
23 | }
24 | subprojects {
25 | project.evaluationDependsOn(':app')
26 | }
27 |
28 | tasks.register("clean", Delete) {
29 | delete rootProject.buildDir
30 | }
31 |
--------------------------------------------------------------------------------
/lib/apis/models/following.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 | import 'package:moekey/apis/models/user_full.dart';
3 | import 'package:flutter/foundation.dart';
4 |
5 | part 'following.freezed.dart';
6 |
7 | part 'following.g.dart';
8 |
9 | @freezed
10 | abstract class Following with _$Following {
11 | const factory Following({
12 | required DateTime createdAt,
13 | UserFullModel? followee,
14 | required String followeeId,
15 | UserFullModel? follower,
16 | required String followerId,
17 | required String id,
18 | }) = _Following;
19 |
20 | factory Following.fromJson(Map json) =>
21 | _$FollowingFromJson(json);
22 | }
23 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // 使用 IntelliSense 了解相关属性。
3 | // 悬停以查看现有属性的描述。
4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "MoeKey",
9 | "request": "launch",
10 | "type": "dart"
11 | },
12 | {
13 | "name": "MoeKey (profile mode)",
14 | "request": "launch",
15 | "type": "dart",
16 | "flutterMode": "profile"
17 | },
18 | {
19 | "name": "MoeKey (release mode)",
20 | "request": "launch",
21 | "type": "dart",
22 | "flutterMode": "release"
23 | }
24 | ]
25 | }
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/lib/widgets/mk_dialog.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:moekey/widgets/mk_modal.dart';
3 |
4 | import 'mk_card.dart';
5 |
6 | class MkDialog extends StatelessWidget {
7 | const MkDialog({super.key, required this.child, this.padding});
8 |
9 | final EdgeInsetsGeometry? padding;
10 | final Widget child;
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 | // 设置
15 | return ModalWrapper(
16 | child: MkCard(
17 | borderRadius: const BorderRadius.all(Radius.circular(24)),
18 | padding: padding,
19 | child: ConstrainedBox(
20 | constraints: const BoxConstraints(maxWidth: 600, minWidth: 300),
21 | child: child,
22 | ),
23 | ));
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/lib/pages/settings/test/test_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:go_router/go_router.dart';
3 | import 'package:hooks_riverpod/hooks_riverpod.dart';
4 | import 'package:moekey/widgets/mk_scaffold.dart';
5 |
6 | class SettingsTestPage extends HookConsumerWidget {
7 | const SettingsTestPage({super.key, required this.text});
8 |
9 | final String text;
10 |
11 | @override
12 | Widget build(BuildContext context, WidgetRef ref) {
13 | return MkScaffold(
14 | body: ListView(
15 | children: [
16 | ListTile(
17 | title: Text(text),
18 | ),
19 | FilledButton(onPressed: () => context.pop(), child: Text("back"))
20 | ],
21 | ),
22 | );
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/lib/status/misskey_api.dart:
--------------------------------------------------------------------------------
1 | import 'package:moekey/apis/index.dart';
2 | import 'package:moekey/status/global_snackbar.dart';
3 | import 'package:riverpod_annotation/riverpod_annotation.dart';
4 |
5 | import '../generated/l10n.dart';
6 | import 'server.dart';
7 |
8 | part 'misskey_api.g.dart';
9 |
10 | @Riverpod(keepAlive: true)
11 | MisskeyApis misskeyApis(MisskeyApisRef ref) {
12 | var user = ref.watch(currentLoginUserProvider);
13 | var instance = user?.serverUrl;
14 | var accessToken = user?.token;
15 | return MisskeyApis(
16 | instance: instance ?? "http://localhost",
17 | accessToken: accessToken ?? "",
18 | onUnauthorized: () {
19 | ref.read(globalSnackbarProvider.notifier).show(S.current.loginExpired);
20 | },
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/windows/runner/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_UTILS_H_
2 | #define RUNNER_UTILS_H_
3 |
4 | #include
5 | #include
6 |
7 | // Creates a console for the process, and redirects stdout and stderr to
8 | // it for both the runner and the Flutter library.
9 | void CreateAndAttachConsole();
10 |
11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string
12 | // encoded in UTF-8. Returns an empty std::string on failure.
13 | std::string Utf8FromUtf16(const wchar_t* utf16_string);
14 |
15 | // Gets the command line arguments passed in as a std::vector,
16 | // encoded in UTF-8. Returns an empty std::vector on failure.
17 | std::vector GetCommandLineArguments();
18 |
19 | #endif // RUNNER_UTILS_H_
20 |
--------------------------------------------------------------------------------
/lib/apis/models/emojis.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 | import 'package:flutter/foundation.dart';
3 |
4 | part 'emojis.freezed.dart';
5 |
6 | part 'emojis.g.dart';
7 |
8 | @freezed
9 | abstract class EmojiSimple with _$EmojiSimple {
10 | const factory EmojiSimple({
11 | required List aliases,
12 | String? category,
13 | bool? isSensitive,
14 | bool? localOnly,
15 | required String name,
16 | List? roleIdsThatCanBeUsedThisEmojiAsReaction,
17 | List? roleIdsThatCanNotBeUsedThisEmojiAsReaction,
18 | required String url,
19 | @Default(false) bool code,
20 | }) = _EmojiSimple;
21 |
22 | factory EmojiSimple.fromJson(Map json) =>
23 | _$EmojiSimpleFromJson(json);
24 | }
25 |
--------------------------------------------------------------------------------
/lib/apis/services/following_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:moekey/apis/services/services.dart';
2 |
3 | class FollowingService extends MisskeyApiServices {
4 | FollowingService({required super.client});
5 |
6 | create({required String userId}) async {
7 | await client.post(
8 | "/following/create",
9 | data: {
10 | "userId": userId,
11 | },
12 | );
13 | }
14 |
15 | delete({required String userId}) async {
16 | await client.post(
17 | "/following/delete",
18 | data: {
19 | "userId": userId,
20 | },
21 | );
22 | }
23 |
24 | requestsCancel({required String userId}) async {
25 | await client.post(
26 | "/following/requests/cancel",
27 | data: {
28 | "userId": userId,
29 | },
30 | );
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/lib/apis/models/clips.dart:
--------------------------------------------------------------------------------
1 | import 'package:freezed_annotation/freezed_annotation.dart';
2 | import 'package:flutter/foundation.dart';
3 | import 'package:moekey/apis/models/user_lite.dart';
4 |
5 | part 'clips.freezed.dart';
6 |
7 | part 'clips.g.dart';
8 |
9 | @freezed
10 | abstract class ClipsModel with _$ClipsModel {
11 | const factory ClipsModel({
12 | required DateTime createdAt,
13 | String? description,
14 | required int favoritedCount,
15 | required String id,
16 | required bool isFavorited,
17 | required bool isPublic,
18 | DateTime? lastClippedAt,
19 | required String name,
20 | required UserLiteModel user,
21 | required String userId,
22 | }) = _ClipsModel;
23 |
24 | factory ClipsModel.fromJson(Map json) =>
25 | _$ClipsModelFromJson(json);
26 | }
27 |
--------------------------------------------------------------------------------
/lib/database/link_preview.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:hive/hive.dart';
4 |
5 | import 'init_database.dart';
6 | import '../apis/models/note.dart' as note;
7 |
8 | class LinkPreviewDatabase {
9 | LazyBox? _box;
10 |
11 | Future> _getDatabase() async {
12 | _box ??= await openLazyDatabase(name: "link_preview");
13 | return _box!;
14 | }
15 |
16 | put(String src, note.LinkPreview link) async {
17 | var db = await _getDatabase();
18 | await db.put(src, jsonEncode(link.toJson()));
19 | }
20 |
21 | Future get(String src) async {
22 | var db = await _getDatabase();
23 | var res = await db.get(src);
24 | if (res != null) {
25 | return note.LinkPreview.fromJson(jsonDecode(res));
26 | }
27 | return null;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/widgets/driver/driver_select_dialog/driver_select_dialog_state.dart:
--------------------------------------------------------------------------------
1 | import 'dart:collection';
2 |
3 | import 'package:moekey/apis/models/drive.dart';
4 | import 'package:riverpod_annotation/riverpod_annotation.dart';
5 |
6 | part 'driver_select_dialog_state.g.dart';
7 |
8 | @Riverpod(keepAlive: true)
9 | class DriverSelectDialogState extends _$DriverSelectDialogState {
10 | @override
11 | LinkedHashMap build() {
12 | return LinkedHashMap();
13 | }
14 |
15 | add(String id, DriveFileModel data) {
16 | state[id] = data;
17 | ref.notifyListeners();
18 | }
19 |
20 | remove(String id) {
21 | if (state[id] != null) {
22 | state.remove(id);
23 | ref.notifyListeners();
24 | }
25 | }
26 |
27 | clear() {
28 | state.clear();
29 | ref.notifyListeners();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lib/widgets/blur_widget.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:hooks_riverpod/hooks_riverpod.dart';
5 | import 'package:moekey/status/themes.dart';
6 |
7 | class BlurWidget extends ConsumerWidget {
8 | final Widget? child;
9 | final Color? color;
10 |
11 | const BlurWidget({
12 | super.key,
13 | this.child,
14 | this.color,
15 | });
16 |
17 | @override
18 | Widget build(BuildContext context, WidgetRef ref) {
19 | var themes = ref.watch(themeColorsProvider);
20 | return ClipRect(
21 | child: BackdropFilter(
22 | filter: ImageFilter.blur(sigmaX: 15.0, sigmaY: 15.0),
23 | child: DecoratedBox(
24 | decoration: BoxDecoration(color: color ?? themes.headerColor),
25 | child: child,
26 | ),
27 | ),
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/widgets/login/servers_select_state.dart:
--------------------------------------------------------------------------------
1 | import 'package:moekey/status/dio.dart';
2 | import 'package:riverpod_annotation/riverpod_annotation.dart';
3 |
4 | part 'servers_select_state.g.dart';
5 |
6 | @riverpod
7 | class InstanceListState extends _$InstanceListState {
8 | @override
9 | FutureOr> build() async {
10 | var http = await ref.watch(httpProvider.future);
11 | var response =
12 | await http.get("https://instanceapp.misskey.page/instances.json");
13 | return response.data['instancesInfos'];
14 | }
15 | }
16 |
17 | List instanceListFilter(List list, String filter) {
18 | var res = [];
19 | for (var element in list) {
20 | if (element["url"].toString().contains(filter) ||
21 | element["name"].toString().contains(filter)) {
22 | res.add(element);
23 | }
24 | }
25 | return res;
26 | }
27 |
--------------------------------------------------------------------------------
/lib/database/notes.dart:
--------------------------------------------------------------------------------
1 | import 'package:hive/hive.dart';
2 | import 'package:moekey/apis/models/note.dart';
3 |
4 | import 'init_database.dart';
5 |
6 | class NotesDatabase {
7 | /// 服务器地址
8 | String server;
9 | LazyBox? _box;
10 |
11 | NotesDatabase({required this.server});
12 |
13 | Future _getDatabase() async {
14 | _box ??=
15 | await openLazyDatabase(name: "notes_cache", server: server);
16 | return _box!;
17 | }
18 |
19 | put(String noteId, NoteModel note) async {
20 | var db = await _getDatabase();
21 | await db.put(noteId, note.toJson());
22 | }
23 |
24 | Future get(String noteId) async {
25 | var db = await _getDatabase();
26 | var res = await db.get(noteId);
27 | if (res != null) {
28 | return NoteModel.fromJson(res);
29 | }
30 | return null;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/lib/utils/custom_rect_tween.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/animation.dart';
2 |
3 | class CustomRectTween extends RectTween {
4 | CustomRectTween({this.a, this.b}) : super(begin: a, end: b);
5 | final Rect? a;
6 | final Rect? b;
7 |
8 | @override
9 | Rect lerp(double t) {
10 | // Curves.elasticOut.transform(t);
11 | //any curve can be applied here e.g. Curve.elasticOut.transform(t);
12 | // final verticalDist = Cubic(0.72, 0.15, 0.5, 1).transform(t);
13 |
14 | final top = lerpDouble(a?.top, b?.top, t) * (1 - t);
15 | return Rect.fromLTRB(
16 | lerpDouble(a?.left, b?.left, t),
17 | top,
18 | lerpDouble(a?.right, b?.right, t),
19 | lerpDouble(a?.bottom, b?.bottom, t),
20 | );
21 | }
22 |
23 | double lerpDouble(num? a, num? b, double t) {
24 | a ??= 0.0;
25 | b ??= 0.0;
26 | return a + (b - a) * t;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 11.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/lib/database/users.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:flutter/foundation.dart';
4 | import 'package:hive/hive.dart';
5 | import 'package:moekey/apis/models/user_full.dart';
6 | import 'package:moekey/database/init_database.dart';
7 |
8 | class UsersDatabase {
9 | /// 服务器地址
10 | String server;
11 |
12 | /// 用户ID
13 | String userId;
14 |
15 | UsersDatabase({required this.server, required this.userId});
16 |
17 | Future> _getDatabase() async {
18 | return openLazyDatabase(name: "users_cache");
19 | }
20 |
21 | put(UserFullModel userFullModel) async {
22 | var db = await _getDatabase();
23 | compute((message) {
24 | var json = jsonEncode(message);
25 | db.put(message.id, json);
26 | }, userFullModel);
27 | }
28 |
29 | get(String id) async {
30 | var db = await _getDatabase();
31 | return db.get(id);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/lib/utils/time_ago_since_date.dart:
--------------------------------------------------------------------------------
1 | import '../generated/l10n.dart';
2 |
3 | String timeAgoSinceDate(DateTime notificationDate) {
4 | final date2 = DateTime.now();
5 | final difference = date2.difference(notificationDate);
6 |
7 | if (difference.inSeconds < 10) {
8 | return S.current.justNow;
9 | } else if (difference.inSeconds < 60) {
10 | return S.current.secondsAgo(difference.inSeconds);
11 | } else if (difference.inMinutes < 60) {
12 | return S.current.minutesAgo(difference.inMinutes);
13 | } else if (difference.inHours < 24) {
14 | return S.current.hoursAgo(difference.inHours);
15 | } else if (difference.inDays < 30) {
16 | return S.current.daysAgo(difference.inDays);
17 | } else if (difference.inDays < 365) {
18 | return S.current.monthsAgo((difference.inDays / 30).floor());
19 | } else {
20 | return S.current.yearsAgo((difference.inDays / 365).floor());
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/lib/widgets/mk_switch.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:hooks_riverpod/hooks_riverpod.dart';
3 |
4 | import '../status/themes.dart';
5 |
6 | class MkSwitch extends ConsumerWidget {
7 | const MkSwitch({
8 | super.key,
9 | required this.value,
10 | this.onChanged,
11 | });
12 |
13 | final bool value;
14 | final void Function(bool value)? onChanged;
15 |
16 | @override
17 | Widget build(BuildContext context, WidgetRef ref) {
18 | var themes = ref.watch(themeColorsProvider);
19 | return Switch(
20 | value: value,
21 | activeColor: themes.switchOnFgColor,
22 | inactiveThumbColor: themes.switchOffFgColor,
23 | activeTrackColor: themes.switchOnBgColor,
24 | inactiveTrackColor: themes.switchOffBgColor,
25 | trackOutlineColor: WidgetStateProperty.all(Colors.transparent),
26 | onChanged: onChanged,
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/linux/flutter/generated_plugins.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # Generated file, do not edit.
3 | #
4 |
5 | list(APPEND FLUTTER_PLUGIN_LIST
6 | media_kit_libs_linux
7 | media_kit_video
8 | url_launcher_linux
9 | )
10 |
11 | list(APPEND FLUTTER_FFI_PLUGIN_LIST
12 | )
13 |
14 | set(PLUGIN_BUNDLED_LIBRARIES)
15 |
16 | foreach(plugin ${FLUTTER_PLUGIN_LIST})
17 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
18 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
19 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
20 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
21 | endforeach(plugin)
22 |
23 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
24 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
25 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
26 | endforeach(ffi_plugin)
27 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v24/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 | *.g.dart
19 | *.freezed.dart
20 | # The .vscode folder contains launch configuration and tasks you configure in
21 | # VS Code which you may wish to be included in version control, so this line
22 | # is commented out by default.
23 | #.vscode/
24 |
25 | # Flutter/Dart/Pub related
26 | **/doc/api/
27 | **/ios/Flutter/.last_build_id
28 | .dart_tool/
29 | .flutter-plugins
30 | .flutter-plugins-dependencies
31 | .packages
32 | .pub-cache/
33 | .pub/
34 | /build/
35 |
36 | # Symbolication related
37 | app.*.symbols
38 |
39 | # Obfuscation related
40 | app.*.map.json
41 |
42 | # Android Studio will place build artifacts here
43 | /android/app/debug
44 | /android/app/profile
45 | /android/app/release
46 | /android/app/.cxx/
47 |
--------------------------------------------------------------------------------
/.clineignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 | *.g.dart
19 | *.freezed.dart
20 | # The .vscode folder contains launch configuration and tasks you configure in
21 | # VS Code which you may wish to be included in version control, so this line
22 | # is commented out by default.
23 | #.vscode/
24 |
25 | # Flutter/Dart/Pub related
26 | **/doc/api/
27 | **/ios/Flutter/.last_build_id
28 | .dart_tool/
29 | .flutter-plugins
30 | .flutter-plugins-dependencies
31 | .packages
32 | .pub-cache/
33 | .pub/
34 | /build/
35 |
36 | # Symbolication related
37 | app.*.symbols
38 |
39 | # Obfuscation related
40 | app.*.map.json
41 |
42 | # Android Studio will place build artifacts here
43 | /android/app/debug
44 | /android/app/profile
45 | /android/app/release
46 | /android/app/.cxx/
47 | .git
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | def flutterSdkPath = {
3 | def properties = new Properties()
4 | file("local.properties").withInputStream { properties.load(it) }
5 | def flutterSdkPath = properties.getProperty("flutter.sdk")
6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
7 | return flutterSdkPath
8 | }
9 | settings.ext.flutterSdkPath = flutterSdkPath()
10 |
11 | includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
12 |
13 | repositories {
14 | google()
15 | mavenCentral()
16 | gradlePluginPortal()
17 | }
18 |
19 | plugins {
20 | id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
21 | }
22 | }
23 |
24 | plugins {
25 | id "dev.flutter.flutter-plugin-loader" version "1.0.0"
26 | id "com.android.application" version "8.7.0" apply false
27 | }
28 |
29 | include ":app"
30 |
--------------------------------------------------------------------------------
/lib/pages/user_widgets/widgets_list/view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:hooks_riverpod/hooks_riverpod.dart';
3 | import 'package:moekey/status/themes.dart';
4 |
5 | import '../../../generated/l10n.dart';
6 |
7 | class WidgetsListPage extends ConsumerWidget {
8 | const WidgetsListPage({super.key});
9 |
10 | @override
11 | Widget build(BuildContext context, WidgetRef ref) {
12 | var theme = ref.watch(themeColorsProvider);
13 | return SizedBox(
14 | width: 350,
15 | height: double.infinity,
16 | child: DecoratedBox(
17 | decoration: BoxDecoration(
18 | border: Border(
19 | left: BorderSide(color: theme.dividerColor, width: 1),
20 | ),
21 | ),
22 | child: SingleChildScrollView(
23 | child: Column(
24 | children: [Text(S.current.userWidgetUnSupport)],
25 | ),
26 | ),
27 | ),
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/README.zh_CN.md:
--------------------------------------------------------------------------------
1 | [English](./README.md) | 简体中文
2 |
3 | 
4 |
5 | [](https://crowdin.com/project/moekey)
6 |
7 | # MoeKey
8 |
9 | MoeKey 是由 Flutter 制作的跨平台 misskey 客户端。
10 |
11 | ## 特性
12 |
13 | MoeKey希望成为一个UI风格与原版Misskey保持一致。功能完善的Misskey客户端。
14 |
15 | > 该项目目前正在开发中,存在许多功能缺陷
16 |
17 | 目前已经实现的功能:
18 |
19 | - 多用户登录
20 | - 时间线查看、搜索
21 | - 帖子的发布相关功能
22 | - 通知查看
23 | - 便签
24 | - 系统公告
25 | - 发现
26 | - HashTag 浏览
27 |
28 | 暂时未实现的功能
29 |
30 | - 个人资料编辑
31 | - Misskey设置
32 | - 天线,频道,列表
33 | - 用户小组件
34 | - 用户成就
35 |
36 | ## 下载
37 |
38 | - [GitHub Releases](https://github.com/MoeKeyDev/MoeKey/releases/latest)
39 |
40 | ## 截图
41 |
42 | 
43 |
44 | ## 开发人员
45 |
46 | ### 本地化
47 |
48 | 帮助我们将 MoeKey 翻译成您的语言,请登录 [Crowdin](https://crowdin.com/project/moekey)
49 |
50 | ### 代码生成
51 |
52 | Riverpod 代码生成
53 |
54 | ```shell
55 | dart run build_runner watch --use-polling-watcher
56 | ```
--------------------------------------------------------------------------------
/lib/widgets/hashtag/hashtag_select_dialog_state.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:moekey/status/misskey_api.dart';
4 | import 'package:riverpod_annotation/riverpod_annotation.dart';
5 |
6 | part 'hashtag_select_dialog_state.g.dart';
7 |
8 | @riverpod
9 | class HashtagSelectDialogState extends _$HashtagSelectDialogState {
10 | Timer? timer;
11 |
12 | @override
13 | FutureOr build() async {
14 | return [];
15 | }
16 |
17 | search({String? query}) {
18 | // 防抖
19 | timer?.cancel();
20 | state = const AsyncLoading();
21 | timer = Timer(const Duration(seconds: 1), () {
22 | _search(query: query);
23 | });
24 | }
25 |
26 | _search({String? query}) async {
27 | if (query == null) {
28 | state = const AsyncData([]);
29 | return;
30 | }
31 |
32 | var http = ref.read(misskeyApisProvider);
33 | var data = await http.hashtags.search(query: query);
34 | state = AsyncData(data);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/windows/runner/runner.exe.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PerMonitorV2
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/windows/flutter/generated_plugins.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # Generated file, do not edit.
3 | #
4 |
5 | list(APPEND FLUTTER_PLUGIN_LIST
6 | gal
7 | media_kit_libs_windows_video
8 | media_kit_video
9 | share_plus
10 | url_launcher_windows
11 | volume_controller
12 | )
13 |
14 | list(APPEND FLUTTER_FFI_PLUGIN_LIST
15 | )
16 |
17 | set(PLUGIN_BUNDLED_LIBRARIES)
18 |
19 | foreach(plugin ${FLUTTER_PLUGIN_LIST})
20 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
21 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
22 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
23 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
24 | endforeach(plugin)
25 |
26 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
27 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
28 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
29 | endforeach(ffi_plugin)
30 |
--------------------------------------------------------------------------------
/lib/utils/format_duration.dart:
--------------------------------------------------------------------------------
1 | import '../generated/l10n.dart';
2 |
3 | String formatDuration(int milliseconds) {
4 | int seconds = (milliseconds / 1000).truncate();
5 | int minutes = (seconds / 60).truncate();
6 | int hours = (minutes / 60).truncate();
7 | int days = (hours / 24).truncate();
8 |
9 | String twoDigits(int n) => n.toString().padLeft(2, "0");
10 | String twoDigitMinutes = twoDigits(minutes.remainder(60));
11 | String twoDigitSeconds = twoDigits(seconds.remainder(60));
12 | String twoDigitHours = twoDigits(hours.remainder(24));
13 |
14 | if (days > 0) {
15 | return S.current
16 | .durationDay(days, twoDigitHours, twoDigitMinutes, twoDigitSeconds);
17 | } else if (hours > 0) {
18 | return S.current
19 | .durationHour(twoDigitHours, twoDigitMinutes, twoDigitSeconds);
20 | } else if (minutes > 0) {
21 | return S.current.durationMinute(twoDigitMinutes, twoDigitSeconds);
22 | } else {
23 | return S.current.durationSecond(twoDigitSeconds);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/lib/pages/timeline/timeline_list.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:hooks_riverpod/hooks_riverpod.dart';
3 | import 'package:moekey/status/timeline.dart';
4 | import 'package:moekey/widgets/notes/note_pagination_list.dart';
5 |
6 | class TimeLineListPage extends HookConsumerWidget {
7 | const TimeLineListPage({super.key, required this.api, this.controller});
8 |
9 | final ScrollController? controller;
10 | final String api;
11 |
12 | @override
13 | Widget build(BuildContext context, WidgetRef ref) {
14 | var dataProvider = timelineProvider(api: api);
15 | var data = ref.watch(dataProvider);
16 | return MkPaginationNoteList(
17 | onLoad: () => ref.read(dataProvider.notifier).load(),
18 | hasMore: data.valueOrNull?.hasMore,
19 | items: data.valueOrNull?.list,
20 | onRefresh: () async {
21 | await ref.read(dataProvider.notifier).cleanCache();
22 | return await ref.refresh(dataProvider.future);
23 | },
24 | );
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lib/pages/notifications/notifications_mentions_list.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:hooks_riverpod/hooks_riverpod.dart';
3 | import 'package:moekey/status/notifications.dart';
4 | import '../../widgets/notes/note_pagination_list.dart';
5 |
6 | class MentionsList extends HookConsumerWidget {
7 | const MentionsList({
8 | super.key,
9 | this.specified = false,
10 | this.padding = EdgeInsets.zero,
11 | });
12 |
13 | final bool specified;
14 | final EdgeInsets padding;
15 |
16 | @override
17 | Widget build(BuildContext context, WidgetRef ref) {
18 | var dataProvider = mentionsNotificationsProvider(specified: specified);
19 | var data = ref.watch(dataProvider);
20 | return MkPaginationNoteList(
21 | padding: padding,
22 | onLoad: () => ref.read(dataProvider.notifier).loadMore(),
23 | onRefresh: () => ref.refresh(dataProvider.future),
24 | items: data.valueOrNull?.list,
25 | hasMore: data.valueOrNull?.hasMore,
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/widgets/keep_alive_wrapper.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class KeepAliveWrapper extends StatefulWidget {
4 | const KeepAliveWrapper({
5 | super.key,
6 | this.keepAlive = true,
7 | required this.child,
8 | });
9 |
10 | final bool keepAlive;
11 | final Widget child;
12 |
13 | @override
14 | KeepAliveWrapperState createState() => KeepAliveWrapperState();
15 | }
16 |
17 | class KeepAliveWrapperState extends State
18 | with AutomaticKeepAliveClientMixin {
19 | @override
20 | Widget build(BuildContext context) {
21 | super.build(context);
22 | return widget.child;
23 | }
24 |
25 | @override
26 | void didUpdateWidget(covariant KeepAliveWrapper oldWidget) {
27 | if (oldWidget.keepAlive != widget.keepAlive) {
28 | // keepAlive 状态需要更新,实现在 AutomaticKeepAliveClientMixin 中
29 | updateKeepAlive();
30 | }
31 | super.didUpdateWidget(oldWidget);
32 | }
33 |
34 | @override
35 | bool get wantKeepAlive => widget.keepAlive;
36 | }
37 |
--------------------------------------------------------------------------------
/lib/hook/use_mk_refresh_load_list_controller.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/widgets.dart';
2 | import 'package:flutter_hooks/flutter_hooks.dart';
3 |
4 | import '../widgets/mk_refresh_load.dart';
5 |
6 | MkRefreshLoadListController useMkRefreshLoadListController() {
7 | return use(_MkRefreshLoadListControllerHook());
8 | }
9 |
10 | class _MkRefreshLoadListControllerHook
11 | extends Hook {
12 | @override
13 | HookState>
14 | createState() {
15 | return _MkRefreshLoadListControllerHookState();
16 | }
17 | }
18 |
19 | class _MkRefreshLoadListControllerHookState extends HookState<
20 | MkRefreshLoadListController, _MkRefreshLoadListControllerHook> {
21 | late final controller = MkRefreshLoadListController();
22 |
23 | @override
24 | MkRefreshLoadListController build(BuildContext context) {
25 | return controller;
26 | }
27 |
28 | @override
29 | void dispose() {
30 | controller.dispose();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/lib/pages/users/user_reactions_list.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:hooks_riverpod/hooks_riverpod.dart';
3 | import 'package:moekey/apis/models/note.dart';
4 | import 'package:moekey/widgets/notes/note_pagination_list.dart';
5 |
6 | import '../../status/user.dart';
7 |
8 | class UserReactionsPage extends HookConsumerWidget {
9 | const UserReactionsPage({
10 | super.key,
11 | required this.userId,
12 | });
13 |
14 | final String userId;
15 |
16 | @override
17 | Widget build(BuildContext context, WidgetRef ref) {
18 | var dataProvider = userReactionsListProvider(
19 | userId: userId,
20 | );
21 | var data = ref.watch(dataProvider);
22 | var items = data.valueOrNull?.list ?? (List.empty());
23 | return MkPaginationNoteList(
24 | onLoad: () => ref.read(dataProvider.notifier).load(),
25 | onRefresh: () => ref.refresh(dataProvider.future),
26 | hasMore: data.valueOrNull?.hasMore ?? true,
27 | items: items,
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/windows/runner/flutter_window.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_FLUTTER_WINDOW_H_
2 | #define RUNNER_FLUTTER_WINDOW_H_
3 |
4 | #include
5 | #include
6 |
7 | #include
8 |
9 | #include "win32_window.h"
10 |
11 | // A window that does nothing but host a Flutter view.
12 | class FlutterWindow : public Win32Window {
13 | public:
14 | // Creates a new FlutterWindow hosting a Flutter view running |project|.
15 | explicit FlutterWindow(const flutter::DartProject& project);
16 | virtual ~FlutterWindow();
17 |
18 | protected:
19 | // Win32Window:
20 | bool OnCreate() override;
21 | void OnDestroy() override;
22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
23 | LPARAM const lparam) noexcept override;
24 |
25 | private:
26 | // The project to run.
27 | flutter::DartProject project_;
28 |
29 | // The Flutter instance hosted by this window.
30 | std::unique_ptr flutter_controller_;
31 | };
32 |
33 | #endif // RUNNER_FLUTTER_WINDOW_H_
34 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/linux/flutter/generated_plugin_registrant.cc:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | // clang-format off
6 |
7 | #include "generated_plugin_registrant.h"
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | void fl_register_plugins(FlPluginRegistry* registry) {
14 | g_autoptr(FlPluginRegistrar) media_kit_libs_linux_registrar =
15 | fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitLibsLinuxPlugin");
16 | media_kit_libs_linux_plugin_register_with_registrar(media_kit_libs_linux_registrar);
17 | g_autoptr(FlPluginRegistrar) media_kit_video_registrar =
18 | fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitVideoPlugin");
19 | media_kit_video_plugin_register_with_registrar(media_kit_video_registrar);
20 | g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
21 | fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
22 | url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
23 | }
24 |
--------------------------------------------------------------------------------
/lib/apis/services/auth_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:dio/dio.dart';
2 | import 'package:moekey/apis/models/auth.dart';
3 | import 'package:moekey/apis/services/services.dart';
4 |
5 | class AuthService extends MisskeyApiServices {
6 | AuthService({required super.client});
7 |
8 | Future sessionGenerate(
9 | {required String appSecret}) async {
10 | var data = await client.post(
11 | "/auth/session/generate",
12 | data: {"appSecret": appSecret},
13 | auth: false,
14 | );
15 | if (data != null) {
16 | return SessionGenerateModel.fromJson(data);
17 | }
18 | return null;
19 | }
20 |
21 | ///
22 | /// {"appSecret": appSecret, "token": token}
23 | Future