Merge branch 'main' into hide-no-permission-unpin

This commit is contained in:
ggurdin 2025-06-18 14:56:15 -04:00 committed by GitHub
commit c5dd7dd09e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 263 additions and 497 deletions

View file

@ -1,20 +1,22 @@
version: 2
updates:
- package-ecosystem: "pub"
directory: "/"
schedule:
interval: "daily"
allow:
- dependency-name: "*"
commit-message:
prefix: "build: "
include: "scope"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
allow:
- dependency-name: "*"
commit-message:
prefix: "build: "
include: "scope"
# #Pangea
# version: 2
# updates:
# - package-ecosystem: "pub"
# directory: "/"
# schedule:
# interval: "daily"
# allow:
# - dependency-name: "*"
# commit-message:
# prefix: "build: "
# include: "scope"
# - package-ecosystem: "github-actions"
# directory: "/"
# schedule:
# interval: "daily"
# allow:
# - dependency-name: "*"
# commit-message:
# prefix: "build: "
# include: "scope"
# Pangea#

View file

@ -1,41 +0,0 @@
name: Auto Pull Request
#on:
# schedule:
# - cron: '0 0 * * 0' # Run at midnight (00:00) every Sunday
on:
push:
branches:
- auto-pr # Change this to match your main branch name
jobs:
auto_pull_request:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Test
run: echo ${{ github.head_ref }}.${{ github.sha }}
- name: Pull changes from FluffyChat
run: |
git config --global user.email "${{ vars.CI_EMAIL }}"
git config --global user.name "${{ vars.CI_USERNAME }}"
git remote add fluffychat https://github.com/krille-chan/fluffychat
git fetch fluffychat main
git merge --no-edit fluffychat/main --allow-unrelated-histories
- name: Push changes
run: |
git push origin HEAD:main-update-fluffy-automatic
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.GH_TOKEN }}
title: Updated fork with new fluffy changes
body: |
This is an automatic PR created by GitHub Actions.
branch: main

View file

@ -1,79 +0,0 @@
name: build-ios
on:
workflow_call:
inputs:
screenshot:
type: string
required: true
ipa:
description: 'Run IPA build'
type: string
required: true
workflow_dispatch:
inputs:
screenshot:
description: 'Run screenshot build'
type: choice
options: ['true', 'false']
required: true
ipa:
description: 'Run IPA build'
type: choice
options: ['true', 'false']
required: true
jobs:
build-ios:
runs-on: macos-latest
timeout-minutes: 20
defaults:
run:
working-directory: ios
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: 'echo "$API_KEY" | base64 --decode > AuthKey.p8'
shell: bash
env:
API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
- run: bundle install
- run: bundle exec fastlane versioning
- name: Flutter
uses: subosito/flutter-action@v2
with:
cache: true
cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:'
cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:"
- run: flutter build ios --simulator --target=integration_test/screenshot_test.dart
if: ${{ inputs.screenshot == 'true' }}
- name: Archive integration ipa
if: ${{ inputs.screenshot == 'true' }}
uses: actions/upload-artifact@v4
with:
name: app-simulator-build
path: build/ios/iphonesimulator/Runner.app
if-no-files-found: error
retention-days: 3
# Build ios Release
- run: flutter build ios --release --config-only --no-codesign --target=lib/main.dart
if: ${{ inputs.ipa == 'true' }}
- run: bundle exec fastlane build
if: ${{ inputs.ipa == 'true' }}
- name: Archive ipa
if: ${{ inputs.ipa == 'true' }}
uses: actions/upload-artifact@v4
with:
name: Runner.ipa
path: ios/Runner.ipa
if-no-files-found: error
retention-days: 3

View file

@ -1,39 +0,0 @@
# name: Dart Code Formatter
# on:
# pull_request:
# push:
# branches: main
# jobs:
# format:
# runs-on: ubuntu-latest
# steps:
# - name: Checkout code
# uses: actions/checkout@v3
# with:
# ref: ${{ github.head_ref }}
# - run: cat .github/workflows/versions.env >> $GITHUB_ENV
# - uses: subosito/flutter-action@v2
# with:
# flutter-version: ${{ env.FLUTTER_VERSION }}
# cache: true
# - name: Auto-format Dart code
# run: |
# dart format lib/ test/
# dart run import_sorter:main --no-comments
# if ! git diff --exit-code; then
# git config user.name "github-actions[bot]"
# git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
# git add .
# git commit -m "generated"
# git push
# fi
# - name: Check for unformatted files
# if: ${{ failure() }}
# run: |
# echo "Code was formatted. Please verify the changes in the PR."

View file

@ -1,107 +1,105 @@
name: Pull Request Workflow
# #Pangea
# name: Pull Request Workflow
on:
pull_request:
merge_group:
# on:
# pull_request:
# merge_group:
jobs:
code_tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: ./scripts/generate-locale-config.sh
- run: git diff --exit-code
- run: cat .github/workflows/versions.env >> $GITHUB_ENV
- uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- run: flutter pub get
- run: flutter gen-l10n
- name: Check formatting
run: dart format lib/ test/ --set-exit-if-changed
- name: Check import formatting
run: dart run import_sorter:main --no-comments --exit-if-changed
- name: Check license compliance
run: dart run license_checker check-licenses -c licenses.yaml --problematic
- run: flutter analyze
# #Pangea - Commented out the following lines, we already have fcm enabled by default
# - name: Apply google services patch
# run: git apply ./scripts/enable-android-google-services.patch
# Pangea#
- run: flutter analyze
- run: flutter test
# jobs:
# code_tests:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# - run: ./scripts/generate-locale-config.sh
# - run: git diff --exit-code
# - run: cat .github/workflows/versions.env >> $GITHUB_ENV
# - uses: subosito/flutter-action@v2
# with:
# flutter-version: ${{ env.FLUTTER_VERSION }}
# cache: true
# - run: flutter pub get
# - run: flutter gen-l10n
# - name: Check formatting
# run: dart format lib/ test/ --set-exit-if-changed
# - name: Check import formatting
# run: dart run import_sorter:main --no-comments --exit-if-changed
# - name: Check license compliance
# run: dart run license_checker check-licenses -c licenses.yaml --problematic
# - run: flutter analyze
# - name: Apply google services patch
# run: git apply ./scripts/enable-android-google-services.patch
# - run: flutter analyze
# - run: flutter test
build_apk:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cat .github/workflows/versions.env >> $GITHUB_ENV
- uses: actions/setup-java@v4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: "zulu"
- uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: false
- run: flutter pub get
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@main
with:
# this might remove tools that are actually needed,
# if set to "true" but frees about 6 GB
tool-cache: false
android: false
- run: flutter build apk --debug
# build_apk:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# - run: cat .github/workflows/versions.env >> $GITHUB_ENV
# - uses: actions/setup-java@v4
# with:
# java-version: ${{ env.JAVA_VERSION }}
# distribution: "zulu"
# - uses: subosito/flutter-action@v2
# with:
# flutter-version: ${{ env.FLUTTER_VERSION }}
# cache: false
# - run: flutter pub get
# - name: Free Disk Space (Ubuntu)
# uses: jlumbroso/free-disk-space@main
# with:
# # this might remove tools that are actually needed,
# # if set to "true" but frees about 6 GB
# tool-cache: false
# android: false
# - run: flutter build apk --debug
build_web:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cat .github/workflows/versions.env >> $GITHUB_ENV
- uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: false
- run: flutter pub get
- name: Prepare web
run: ./scripts/prepare-web.sh
- run: flutter build web
# build_web:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# - run: cat .github/workflows/versions.env >> $GITHUB_ENV
# - uses: subosito/flutter-action@v2
# with:
# flutter-version: ${{ env.FLUTTER_VERSION }}
# cache: false
# - run: flutter pub get
# - name: Prepare web
# run: ./scripts/prepare-web.sh
# - run: flutter build web
# #Pangea
# commented out because we do not build Pangea Chat to linux
# build_debug_linux:
# strategy:
# matrix:
# arch: [ x64, arm64 ]
# runs-on: ${{ matrix.arch == 'arm64' && 'self-hosted' || 'ubuntu-latest'}}
# steps:
# - uses: actions/checkout@v4
# - run: cat .github/workflows/versions.env >> $GITHUB_ENV
# - name: Install dependencies
# run: sudo apt-get update && sudo apt-get install git wget curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 libssl-dev libwebkit2gtk-4.1-dev -y
# - name: Install Flutter
# run: |
# git clone --branch ${{ env.FLUTTER_VERSION }} https://github.com/flutter/flutter.git
# ./flutter/bin/flutter doctor
# - run: ./flutter/bin/flutter pub get
# - run: ./flutter/bin/flutter build linux --target-platform linux-${{ matrix.arch }}
# Pangea#
# commented out because we do not build Pangea Chat to linux
# build_debug_linux:
# strategy:
# matrix:
# arch: [ x64, arm64 ]
# runs-on: ${{ matrix.arch == 'arm64' && 'self-hosted' || 'ubuntu-latest'}}
# steps:
# - uses: actions/checkout@v4
# - run: cat .github/workflows/versions.env >> $GITHUB_ENV
# - name: Install dependencies
# run: sudo apt-get update && sudo apt-get install git wget curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 libssl-dev libwebkit2gtk-4.1-dev -y
# - name: Install Flutter
# run: |
# git clone --branch ${{ env.FLUTTER_VERSION }} https://github.com/flutter/flutter.git
# ./flutter/bin/flutter doctor
# - run: ./flutter/bin/flutter pub get
# - run: ./flutter/bin/flutter build linux --target-platform linux-${{ matrix.arch }}
build_debug_ios:
runs-on: macos-15
steps:
- uses: actions/checkout@v4
- run: cat .github/workflows/versions.env >> $GITHUB_ENV
- uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
cache: true
- name: Setup Xcode version
uses: maxim-lobanov/setup-xcode@v1.6.0
with:
xcode-version: latest
- run: brew install sqlcipher
- run: flutter pub get
- run: flutter build ipa --no-codesign
# build_debug_ios:
# runs-on: macos-15
# steps:
# - uses: actions/checkout@v4
# - run: cat .github/workflows/versions.env >> $GITHUB_ENV
# - uses: subosito/flutter-action@v2
# with:
# flutter-version: ${{ env.FLUTTER_VERSION }}
# cache: true
# - name: Setup Xcode version
# uses: maxim-lobanov/setup-xcode@v1.6.0
# with:
# xcode-version: latest
# - run: brew install sqlcipher
# - run: flutter pub get
# - run: flutter build ipa --no-codesign
# Pangea#

View file

@ -77,13 +77,4 @@ jobs:
bundle install
bundle update fastlane
bundle exec fastlane deploy_internal_test
cd ..
deploy_ios_testflight: # stashed on old.yml
environment:
name: ${{ inputs.environment }}
env:
WEB_APP_ENV: ${{ vars.WEB_APP_ENV }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
cd ..

View file

@ -1,26 +0,0 @@
# name: Matrix Notification
# on:
# issues:
# types: [ opened ]
# issue_comment:
# types: [ created ]
# jobs:
# notify:
# runs-on: ubuntu-latest
# steps:
# - name: Send Matrix Notification
# env:
# MATRIX_URL: https://matrix.janian.de/_matrix/client/v3/rooms/${{ secrets.MATRIX_MANAGEMENT_ROOM }}/send/m.room.message
# run: |
# if [ "${{ github.event.action }}" == "opened" ]; then
# PAYLOAD="{\"msgtype\": \"m.notice\", \"body\": \"New Issue from ${{ github.event.issue.user.login }}\\n${{ github.event.issue.title }}\\n\\n${{ github.event.issue.body }}\\n\\nURL: ${{ github.event.issue.html_url }}\"}"
# elif [ "${{ github.event.action }}" == "created" ]; then
# PAYLOAD="{\"msgtype\": \"m.notice\", \"body\": \"New Comment from ${{ github.event.comment.user.login }}\\n\\n${{ github.event.comment.body }}\\n\\nURL: ${{ github.event.comment.html_url }}\"}"
# fi
# curl -X POST -H "Authorization: Bearer ${{ secrets.MATRIX_BOT_TOKEN }}" \
# -H "Content-Type: application/json" \
# -d "$PAYLOAD" \
# $MATRIX_URL

View file

@ -1,44 +0,0 @@
name: Old Release Workflow
on:
push:
branches:
- master-unused
concurrency:
group: release_workflow
cancel-in-progress: true
jobs:
deploy_ios_internal:
runs-on: macos-latest
environment: staging
steps:
- uses: actions/checkout@v4
- run: cat ../.github/workflows/versions.env >> $GITHUB_ENV
- name: Flutter
uses: subosito/flutter-action@v2
with:
cache: true
cache-key: 'flutter-:os:-:channel:-:version:-:arch:-:hash:'
cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:"
# Build ios Release
- run: flutter build ios --release --config-only --no-codesign --target=lib/main.dart
- name: Deploy ios
run: |
mkdir -p build/ios
cp build/app/outputs/bundle/release/app-release.aab build/ios/
cd ios
bundle install
bundle update fastlane
cd ..
- name: Execute fastlane signing
env:
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
APP_STORE_CONNECT_API_KEY_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY_ID }}
APP_STORE_CONNECT_API_KEY_IS_KEY_CONTENT_BASE64: ${{ secrets.APP_STORE_CONNECT_API_KEY_IS_KEY_CONTENT_BASE64 }}
APP_STORE_CONNECT_API_KEY_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY_KEY }}
run: bundle exec fastlane ios beta

View file

@ -142,36 +142,39 @@ jobs:
asset_path: build/app/outputs/flutter-apk/app-release.apk
asset_name: pangeachat.apk
asset_content_type: application/vnd.android.package-archive
build_linux:
strategy:
matrix:
arch: [ x64 ]
runs-on: ubuntu-latest
needs: create_release
steps:
- uses: actions/checkout@v4
- run: cat .github/workflows/versions.env >> $GITHUB_ENV
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 libssl-dev libwebkit2gtk-4.1-dev -y
- name: Install dependencies for audio-player
run: sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
- name: Install Flutter
run: |
git clone --branch ${{ env.FLUTTER_VERSION }} https://github.com/flutter/flutter.git
./flutter/bin/flutter doctor
- run: ./flutter/bin/flutter pub get
- run: ./flutter/bin/flutter build linux --target-platform linux-${{ matrix.arch }}
- name: Create archive
run: tar -czf pangeachat-linux-${{ matrix.arch }}.tar.gz -C build/linux/${{ matrix.arch }}/release/bundle/ .
- name: Upload to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.PAGES_DEPLOY_TOKEN }}
with:
upload_url: ${{ needs.create_release.outputs.upload_url }}
asset_path: pangeachat-linux-${{ matrix.arch }}.tar.gz
asset_name: pangeachat-linux-${{ matrix.arch }}.tar.gz
asset_content_type: application/gzip
# #Pangea
# build_linux:
# strategy:
# matrix:
# arch: [ x64 ]
# runs-on: ubuntu-latest
# needs: create_release
# steps:
# - uses: actions/checkout@v4
# - run: cat .github/workflows/versions.env >> $GITHUB_ENV
# - name: Install dependencies
# run: sudo apt-get update && sudo apt-get install curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 libssl-dev libwebkit2gtk-4.1-dev -y
# - name: Install dependencies for audio-player
# run: sudo apt-get install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
# - name: Install Flutter
# run: |
# git clone --branch ${{ env.FLUTTER_VERSION }} https://github.com/flutter/flutter.git
# ./flutter/bin/flutter doctor
# - run: ./flutter/bin/flutter pub get
# - run: ./flutter/bin/flutter build linux --target-platform linux-${{ matrix.arch }}
# - name: Create archive
# run: tar -czf pangeachat-linux-${{ matrix.arch }}.tar.gz -C build/linux/${{ matrix.arch }}/release/bundle/ .
# - name: Upload to release
# uses: actions/upload-release-asset@v1
# env:
# GITHUB_TOKEN: ${{ secrets.PAGES_DEPLOY_TOKEN }}
# with:
# upload_url: ${{ needs.create_release.outputs.upload_url }}
# asset_path: pangeachat-linux-${{ matrix.arch }}.tar.gz
# asset_name: pangeachat-linux-${{ matrix.arch }}.tar.gz
# asset_content_type: application/gzip
# Pangea#
deploy_web:
runs-on: ubuntu-latest

View file

@ -1,39 +0,0 @@
name: upload-release-ios
on:
workflow_call:
inputs:
new_release:
required: true
type: string
description: "The new release version number"
new_release_notes:
required: true
type: string
description: "The release notes for the new release"
jobs:
build:
runs-on: macos-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download app
uses: actions/download-artifact@v4
with:
name: Runner.ipa
path: ios/
- run: 'echo "$API_KEY" | base64 --decode > AuthKey.p8'
shell: bash
env:
API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
- run: bundle install
- run: bundle exec fastlane upload_testflight
env:
RELEASE_NOTES: ${{ inputs.new_release_notes }}
- run: bundle exec fastlane upload_metadata_app_store

View file

@ -5031,5 +5031,6 @@
"type": "int"
}
}
}
},
"failedToFetchTranscription": "Failed to fetch transcription"
}

View file

@ -185,6 +185,23 @@ class HtmlMessage extends StatelessWidget {
result.add(html.substring(lastEnd)); // Remaining text after last tag
}
final replyTagIndex = result.indexWhere(
(string) => string.contains('<mx-reply>'),
);
if (replyTagIndex != -1) {
final closingReplyTagIndex = result.indexWhere(
(string) => string.contains('</mx-reply>'),
replyTagIndex,
);
if (closingReplyTagIndex != -1) {
result.replaceRange(
replyTagIndex,
closingReplyTagIndex + 1,
[result.sublist(replyTagIndex, closingReplyTagIndex + 1).join()],
);
}
}
for (final PangeaToken token in tokens ?? []) {
final String tokenText = token.text.content;
final substringIndex = result.indexWhere(

View file

@ -9,6 +9,7 @@ import 'package:fluffychat/pangea/learning_settings/models/language_model.dart';
import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_repo.dart';
import 'package:fluffychat/pangea/phonetic_transcription/phonetic_transcription_request.dart';
import 'package:fluffychat/pangea/toolbar/controllers/tts_controller.dart';
import 'package:fluffychat/widgets/hover_builder.dart';
import 'package:fluffychat/widgets/matrix.dart';
class PhoneticTranscriptionWidget extends StatefulWidget {
@ -32,51 +33,61 @@ class PhoneticTranscriptionWidget extends StatefulWidget {
class _PhoneticTranscriptionWidgetState
extends State<PhoneticTranscriptionWidget> {
late Future<String?> _transcriptionFuture;
bool _hovering = false;
bool _isPlaying = false;
bool _isLoading = false;
late final StreamSubscription _loadingChoreoSubscription;
Object? _error;
String? _transcription;
@override
void initState() {
super.initState();
_transcriptionFuture = _fetchTranscription();
_loadingChoreoSubscription =
TtsController.loadingChoreoStream.stream.listen((val) {
if (mounted) setState(() => _isLoading = val);
});
_fetchTranscription();
}
@override
void dispose() {
TtsController.stop();
_loadingChoreoSubscription.cancel();
super.dispose();
}
Future<void> _fetchTranscription() async {
try {
setState(() {
_isLoading = true;
_error = null;
_transcription = null;
});
Future<String?> _fetchTranscription() async {
if (MatrixState.pangeaController.languageController.userL1 == null) {
if (MatrixState.pangeaController.languageController.userL1 == null) {
ErrorHandler.logError(
e: Exception('User L1 is not set'),
data: {
'text': widget.text,
'textLanguageCode': widget.textLanguage.langCode,
},
);
_error = Exception('User L1 is not set');
return;
}
final req = PhoneticTranscriptionRequest(
arc: LanguageArc(
l1: MatrixState.pangeaController.languageController.userL1!,
l2: widget.textLanguage,
),
content: PangeaTokenText.fromString(widget.text),
// arc can be omitted for default empty map
);
final res = await PhoneticTranscriptionRepo.get(req);
_transcription = res.phoneticTranscriptionResult.phoneticTranscription
.first.phoneticL1Transcription.content;
} catch (e, s) {
_error = e;
ErrorHandler.logError(
e: Exception('User L1 is not set'),
e: e,
s: s,
data: {
'text': widget.text,
'textLanguageCode': widget.textLanguage.langCode,
},
);
return widget.text; // Fallback to original text if no L1 is set
} finally {
if (mounted) setState(() => _isLoading = false);
}
final req = PhoneticTranscriptionRequest(
arc: LanguageArc(
l1: MatrixState.pangeaController.languageController.userL1!,
l2: widget.textLanguage,
),
content: PangeaTokenText.fromString(widget.text),
// arc can be omitted for default empty map
);
final res = await PhoneticTranscriptionRepo.get(req);
return res.phoneticTranscriptionResult.phoneticTranscription.first
.phoneticL1Transcription.content;
}
Future<void> _handleAudioTap(BuildContext context) async {
@ -101,55 +112,66 @@ class _PhoneticTranscriptionWidgetState
@override
Widget build(BuildContext context) {
return FutureBuilder<String?>(
future: _transcriptionFuture,
builder: (context, snapshot) {
final transcription = snapshot.data ?? '';
return MouseRegion(
onEnter: (_) => setState(() => _hovering = true),
onExit: (_) => setState(() => _hovering = false),
child: GestureDetector(
onTap: () => _handleAudioTap(context),
child: AnimatedContainer(
duration: const Duration(milliseconds: 150),
decoration: BoxDecoration(
color: _hovering
? Colors.grey.withAlpha((0.2 * 255).round())
: Colors.transparent,
borderRadius: BorderRadius.circular(6),
),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
return HoverBuilder(
builder: (context, hovering) {
return GestureDetector(
onTap: () => _handleAudioTap(context),
child: AnimatedContainer(
duration: const Duration(milliseconds: 150),
decoration: BoxDecoration(
color: hovering
? Colors.grey.withAlpha((0.2 * 255).round())
: Colors.transparent,
borderRadius: BorderRadius.circular(6),
),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (_error != null)
Row(
spacing: 8.0,
children: [
Icon(
Icons.error_outline,
size: widget.iconSize ?? 24,
color: Theme.of(context).colorScheme.error,
),
Text(
L10n.of(context).failedToFetchTranscription,
style: widget.style,
),
],
)
else if (_isLoading || _transcription == null)
const SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator.adaptive(),
)
else
Flexible(
child: Text(
"/${transcription.isNotEmpty ? transcription : widget.text}/",
"/$_transcription/",
style: widget.style ??
Theme.of(context).textTheme.bodyMedium,
),
),
const SizedBox(width: 8),
const SizedBox(width: 8),
if (_transcription != null && _error == null)
Tooltip(
message: _isPlaying
? L10n.of(context).stop
: L10n.of(context).playAudio,
child: _isLoading
? const SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(strokeWidth: 3),
)
: Icon(
_isPlaying ? Icons.pause_outlined : Icons.volume_up,
size: widget.iconSize ?? 24,
color: _isPlaying
? Theme.of(context).colorScheme.primary
: Theme.of(context).iconTheme.color,
),
child: Icon(
_isPlaying ? Icons.pause_outlined : Icons.volume_up,
size: widget.iconSize ?? 24,
color: _isPlaying
? Theme.of(context).colorScheme.primary
: Theme.of(context).iconTheme.color,
),
),
],
),
],
),
),
);