Flutter未知功能插件bluesky的使用(注:由于介绍为undefined,故假设为“未知功能”)

发布于 1周前 作者 yuanlaile 来自 Flutter

Flutter未知功能插件bluesky的使用(注:由于介绍为undefined,故假设为“未知功能”)

1. 概述 🌎

bluesky 是一个用于在 Dart 和 Flutter 应用程序中使用 AT Protocol API 和 Bluesky API 的最强大库。该库跨平台,并且已经在许多应用程序中使用。更多详情请参见 官方展示

1.1. 功能特性 ⭐

  • 零依赖
  • ✅ 支持强大的内置重试机制,使用 指数退避和抖动
  • ✅ 支持所有 app.bsky.* 和 chat.bsky.* 端点
  • ✅ 文档齐全且经过充分测试
  • ✅ 支持强大的 Firehose API
  • ✅ 支持强大的审核 API
  • ✅ 支持 OAuth DPoP
  • ✅ 100% 空安全
  • ✅ 内置 atproto 功能

1.2. 入门指南 💪

安装

pubspec.yaml 文件中添加以下依赖:

dependencies:
  bluesky: ^0.1.0

然后运行 flutter pub getdart pub get

导入

在 Dart 文件中导入 bluesky 包:

import 'package:bluesky/bluesky.dart';

实例化 Bluesky

final bsky = Bluesky.fromSession(
  session,
  service: 'SERVICE_NAME',
  relayService: 'STREAM_SERVICE_NAME',
  retryConfig: RetryConfig(
    maxAttempts: 5,
    jitter: Jitter(minInSeconds: 2, maxInSeconds: 5),
    onExecute: (event) => print(
      'Retry after ${event.intervalInSeconds} seconds... [${event.retryCount} times]',
    ),
  ),
  timeout: Duration(seconds: 20),
);

1.3. 支持的端点 👀

1.4. 更多提示 🏄

1.5. 贡献 🏆

如果您想为 bluesky 做贡献,请创建一个 issue 或提交一个 Pull Request。您可以参考以下资源:

或者您可以在 讨论区 发起讨论。

1.6. 支持 ❤️

最简单的方式是给项目一个星标,您可以在 GitHubPub.dev 上进行操作。

您也可以通过成为 GitHub 赞助者来支持这个项目:

您还可以在您的仓库中使用以下徽章来显示您的应用是使用 bluesky 构建的:

Powered by bluesky Powered by bluesky Powered by bluesky


### 1.7. 许可证 🔑

`bluesky` 的所有资源均在 [BSD-3](https://github.com/myConsciousness/atproto.dart/blob/main/LICENSE) 许可证下提供。

### 1.8. 更多信息 🧐

`bluesky` 由 [Shinya Kato (@myConsciousness)](https://github.com/myConsciousness) 设计和实现。

- [创作者简介](https://github.com/myConsciousness)
- [许可证](https://github.com/myConsciousness/atproto.dart/blob/main/LICENSE)
- [API 文档](https://pub.dev/documentation/bluesky/latest/bluesky/bluesky-library.html)
- [发布说明](https://github.com/myConsciousness/atproto.dart/releases)
- [Bug 报告](https://github.com/myConsciousness/atproto.dart/issues)

## 示例代码

以下是一个简单的示例代码,展示了如何使用 `bluesky` 插件:

```dart
import 'dart:io';

import 'package:atproto_core/atproto_core.dart';
import 'package:atproto_core/atproto_oauth.dart';
import 'package:bluesky/app_bsky_embed_video.dart';
import 'package:bluesky/atproto.dart';
import 'package:bluesky/bluesky.dart';
import 'package:bluesky/bluesky_chat.dart';
import 'package:bluesky/chat_bsky_convo_defs.dart';
import 'package:bluesky/moderation.dart';

/// https://atprotodart.com/docs/packages/bluesky
Future<void> main() async {
  try {
    //! 首先需要与 ATP 服务器建立会话。
    final session = await _session;

    final bsky = Bluesky.fromSession(
      session,
      //! 默认值为 `bsky.social`,或根据会话动态解析
      service: 'SERVICE_NAME',

      //! 默认值为 `bsky.network`
      relayService: 'STREAM_SERVICE_NAME',

      //! 当与 API 通信时发生服务器错误或网络错误时,可以自动重试
      retryConfig: RetryConfig(
        maxAttempts: 5,
        jitter: Jitter(
          minInSeconds: 2,
          maxInSeconds: 5,
        ),
        onExecute: (event) => print(
          'Retry after ${event.intervalInSeconds} seconds...'
          '[${event.retryCount} times]',
        ),
      ),

      //! 默认超时时间为 30 秒。
      timeout: Duration(seconds: 20),
    );

    //! 聊天功能
    final chat = BlueskyChat.fromSession(session);
    final convos = await chat.convo.listConvos();

    for (final convo in convos.data.convos) {
      await chat.convo.sendMessage(
        convoId: convo.id,
        message: MessageInput(text: 'Hello?'),
      );
    }

    //! 审核功能
    final preferences = await bsky.actor.getPreferences();
    final moderationPrefs = preferences.data.getModerationPrefs();
    final labelDefs = await bsky.labeler.getLabelDefinitions(moderationPrefs);

    final moderationOpts = ModerationOpts(
      userDid: bsky.session!.did,
      prefs: moderationPrefs,
      labelDefs: labelDefs,
    );

    //! 获取首页时间线
    final feeds = await bsky.feed.getTimeline(
      headers: getLabelerHeaders(moderationPrefs),
    );

    for (final feed in feeds.data.feed) {
      final decision = moderatePost(
        ModerationSubjectPost.postView(data: feed.post),
        moderationOpts,
      );

      if (decision.getUI(ModerationBehaviorContext.contentView).alert) {
        // 提醒!
      }
    }

    print(feeds);

    //! 上传视频
    final uploadedVideo = await bsky.video.uploadVideo(
      File('./cool_video.mov').readAsBytesSync(),
    );

    //! 发布酷炫内容
    final createdRecord = await bsky.feed.post(
      text: 'Hello, Bluesky!',
      embed: Embed.video(
        data: EmbedVideo(
          video: uploadedVideo.data.blob!,
        ),
      ),
    );

    print(createdRecord);

    //! 删除它
    await bsky.atproto.repo.deleteRecord(
      uri: createdRecord.data.uri,
    );

    //! 可以轻松使用 Stream API
    final subscription = await bsky.atproto.sync.subscribeRepos();

    subscription.data.stream.listen((event) {
      event.when(
        //! 可以非常容易地处理 commit 事件
        //! 使用 RepoCommitAdaptor。
        commit: RepoCommitAdaptor(
          //! 创建事件。
          onCreatePost: (data) => data.record,
          onCreateLike: print,

          //! 更新事件。
          onUpdateProfile: print,

          //! 删除事件。
          onDeletePost: print,
        ).execute,
        identity: print,
        account: print,
        handle: print,
        migrate: print,
        tombstone: print,
        info: print,
        unknown: print,
      );
    });
  } on UnauthorizedException catch (e) {
    print(e);
  } on XRPCException catch (e) {
    print(e);
  }
}

Future<Session> get _session async {
  final session = await createSession(
    service: 'SERVICE_NAME', //! 默认值为 `bsky.social`
    identifier: 'YOUR_HANDLE_OR_EMAIL', //! 如 `shinyakato.bsky.social`
    password: 'YOUR_PASSWORD',
  );

  return session.data;
}

/// Flutter 应用的 OAuth 流程:
// ignore: unused_element
Future<OAuthSession> get _oAuthSession async {
  // 使用您的客户端元数据
  final metadata = await getClientMetadata(
    'https://atprotodart.com/oauth/bluesky/atprotodart/client-metadata.json',
  );

  final oauth = OAuthClient(metadata);

  final (authUrl, ctx) = await oauth.authorize('shinyakato.dev');
  print(authUrl);
  print(ctx);

  // 让用户访问 URL
  // final callback = await FlutterWebAuth2.authenticate(
  //   url: authorizationUrl,
  //   callbackUrlScheme: 'https',
  // );

  final session = await oauth.callback(
    // 回调 URL
    'https://atprotodart.com/oauth/bluesky/auth.html?iss=xxxx&state=xxxxxxx&code=xxxxxxx',
    ctx,
  );
  print(session.accessToken);
  print(session.$dPoPNonce); // 每次请求都会更新
  print(session.$publicKey);
  print(session.$privateKey);

  // 您可以从存储的密钥中恢复 OAuthSession
  final restoredSession = restoreOAuthSession(
    accessToken: session.accessToken,
    refreshToken: session.refreshToken,
    publicKey: session.$publicKey,
    privateKey: session.$privateKey,
  );

  // 如果您想刷新会话
  // final refreshed = await oauth.refresh(bsky.oAuthSession!);

  return restoredSession;
}

希望这些信息对您有所帮助!如果有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter未知功能插件bluesky的使用(注:由于介绍为undefined,故假设为“未知功能”)的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter未知功能插件bluesky的使用(注:由于介绍为undefined,故假设为“未知功能”)的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,当面对一个“未知功能”的插件(比如这里提到的bluesky插件,由于介绍为undefined,我们假设其具体功能未知),通常你需要先查阅该插件的官方文档或源代码来理解其功能和使用方法。然而,在没有具体文档的情况下,我们只能假设一些通用的使用步骤,并通过代码示例来展示如何集成和使用一个Flutter插件。

请注意,以下代码是一个假设性的示例,旨在展示如何在Flutter项目中集成和使用一个插件,而不是针对bluesky插件的具体实现。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加该插件的依赖。由于bluesky是一个假设的插件,这里我们使用一个占位符名称unknown_plugin来代表它:

dependencies:
  flutter:
    sdk: flutter
  unknown_plugin: ^0.0.1  # 假设的版本号

然后运行flutter pub get来安装依赖。

2. 导入插件

在你的Dart文件中导入该插件:

import 'package:unknown_plugin/unknown_plugin.dart';

3. 使用插件

由于我们不知道bluesky(或unknown_plugin)的具体功能,这里我们假设它有一个初始化方法init和一个执行未知操作的方法performUnknownAction。以下是一个假设性的使用示例:

import 'package:flutter/material.dart';
import 'package:unknown_plugin/unknown_plugin.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Bluesky Plugin Example'),
        ),
        body: Center(
          child: BlueskyExample(),
        ),
      ),
    );
  }
}

class BlueskyExample extends StatefulWidget {
  @override
  _BlueskyExampleState createState() => _BlueskyExampleState();
}

class _BlueskyExampleState extends State<BlueskyExample> {
  String result = 'Unknown';

  @override
  void initState() {
    super.initState();
    // 假设的初始化方法
    _initializeBluesky();
  }

  Future<void> _initializeBluesky() async {
    try {
      // 假设的初始化过程
      await UnknownPlugin.init();
      // 执行未知操作
      String actionResult = await UnknownPlugin.performUnknownAction();
      setState(() {
        result = actionResult;
      });
    } catch (e) {
      print('Error initializing Bluesky: $e');
      setState(() {
        result = 'Error: $e';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('Bluesky Plugin Result:'),
        Text(result),
      ],
    );
  }
}

注意事项

  1. 实际插件可能不同:上述代码是基于假设的插件功能编写的,实际插件可能有不同的API和初始化过程。
  2. 查阅文档:在集成和使用任何Flutter插件之前,务必查阅其官方文档以了解正确的使用方法和API。
  3. 错误处理:在调用插件方法时,总是添加适当的错误处理逻辑以处理可能的异常情况。

由于bluesky插件的具体信息未知,以上代码仅作为展示如何在Flutter中集成和使用插件的一个通用示例。在实际项目中,你需要根据插件的官方文档来调整代码。

回到顶部