Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,16 @@ jobs:
- name: Build
working-directory: ${{github.workspace}}
run: |
flutter build apk --target-platform=android-arm,android-arm64
flutter build apk --target-platform=android-arm,android-arm64 --split-per-abi

- name: Upload artifact
- name: Upload artifact (arm8)
uses: actions/upload-artifact@v4
with:
name: app-release.apk
path: ${{github.workspace}}/build/app/outputs/apk/release/app-release.apk
name: SyncTube-arm8.apk
path: ${{github.workspace}}/build/app/outputs/flutter-apk/app-arm64-v8a-release.apk

- name: Upload artifact (arm7)
uses: actions/upload-artifact@v4
with:
name: SyncTube-arm7.apk
path: ${{github.workspace}}/build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk
4 changes: 2 additions & 2 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@
android:name="flutterEmbedding"
android:value="2" />
<!-- todo remove when video_player will be fixed -->
<meta-data
<!-- <meta-data
android:name="io.flutter.embedding.android.EnableImpeller"
android:value="false"
/>
/> -->
<!-- custom: for ota update -->
<provider
android:name="sk.fourq.otaupdate.OtaUpdateFileProvider"
Expand Down
26 changes: 14 additions & 12 deletions lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class _AppState extends State<App> with WidgetsBindingObserver {
super.initState();
app = AppModel(widget.url);
fileUploader = FileUploader(widget.url);
Settings.applySettings(app);
Settings.load(app);
WakelockPlus.enable();
WidgetsBinding.instance.addObserver(this);
final nativeOrientation = NativeDeviceOrientationCommunicator();
Expand Down Expand Up @@ -124,33 +124,37 @@ class _AppState extends State<App> with WidgetsBindingObserver {
direction: orientation == Orientation.landscape
? Axis.horizontal
: Axis.vertical,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Selector<AppModel, bool>(
selector: (context, app) => app.isChatVisible,
builder: (context, isChatVisible, child) {
return Selector<PlayerModel, double>(
selector: (context, player) {
final isInit =
player.controller?.value.isInitialized ?? false;
if (!isInit) return 16 / 9;
return player.controller?.value.aspectRatio ?? 16 / 9;
if (!player.isVideoLoaded()) return 16 / 9;
final width = player.player.state.width;
final height = player.player.state.height;
if (width == null || height == null || height == 0)
return 16 / 9;
return width / height;
},
builder: (context, ratio, child) {
final media = MediaQuery.of(context);
final isLandscape = orientation == Orientation.landscape;
return Container(
color: Colors.black,
padding: EdgeInsets.only(
top: _isKeyboardVisible() ? media.padding.top : 0,
),
width: orientation == Orientation.landscape
width: isLandscape
? isChatVisible
? media.size.width / 1.5
: media.size.width
: double.infinity,
height: playerHeight(ratio),
height: isLandscape ? null : playerHeight(ratio),
child: Column(
children: [
if (orientation == Orientation.landscape &&
if (isLandscape &&
!_isKeyboardVisible() &&
isChatVisible)
ChatPanel(),
Expand Down Expand Up @@ -230,12 +234,10 @@ class _AppState extends State<App> with WidgetsBindingObserver {
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
switch (state) {
case AppLifecycleState.paused:
case .paused:
app.inBackground();
break;
case AppLifecycleState.resumed:
case .resumed:
app.inForeground();
break;
default:
}
}
Expand Down
148 changes: 84 additions & 64 deletions lib/chat.dart
Original file line number Diff line number Diff line change
Expand Up @@ -257,41 +257,14 @@ class _ChatState extends State<Chat> {
AnimatedOpacity(
duration: const Duration(milliseconds: 100),
opacity: showRewindMenu ? 1 : 0,
child: showRewindMenu
? SizedBox(
height: 60,
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.min,
children: [
for (final time in rewindOptions)
Expanded(
child: TextButton(
style: TextButton.styleFrom(
// primary: Theme.of(context).rewindButton,
padding: EdgeInsets.zero,
),
child: Align(
alignment: Alignment.center,
child: Text(time.toString(), maxLines: 1),
),
onPressed: () {
chat.sendMessage('/$time');
setState(() => showRewindMenu = false);
},
),
),
],
),
)
: null,
child: showRewindMenu ? _buildRewindMenu(chat) : null,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
SizedBox(width: 10),
Expanded(
child: TextField(
inputFormatters: [
Expand All @@ -308,6 +281,16 @@ class _ChatState extends State<Chat> {
contentPadding: const EdgeInsets.all(14),
hintText: _hintText(chat),
border: OutlineInputBorder(
borderSide: BorderSide(
width: 2,
),
borderRadius: BorderRadius.circular(20),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 2,
color: Theme.of(context).focusColor,
),
borderRadius: BorderRadius.circular(20),
),
),
Expand Down Expand Up @@ -359,41 +342,9 @@ class _ChatState extends State<Chat> {
},
),
),
if (!chat.isUnknownClient)
GestureDetector(
onLongPress: () {
setState(() => showRewindMenu = !showRewindMenu);
},
child: IconButton(
padding: const EdgeInsets.only(left: 10, right: 20),
onPressed: () {
if (showRewindMenu) {
setState(() => showRewindMenu = false);
return;
}
setState(() {
showEmotesTab = !showEmotesTab;
if (showEmotesTab) {
reopenKeyboard = inputFocus.hasFocus;
inputFocus.unfocus();
} else {
if (reopenKeyboard && textController.text.isNotEmpty)
inputFocus.requestFocus();
reopenKeyboard = false;
}
});
SystemChrome.restoreSystemUIOverlays();
},
// tooltip: 'Show emotes',
icon: Icon(
showRewindMenu ? Icons.close : Icons.mood,
size: 35,
color: showEmotesTab
? Theme.of(context).colorScheme.primary
: Theme.of(context).icon,
),
),
),
chat.isUnknownClient
? SizedBox(width: 10)
: _buildEmotesButton(context),
],
),
if (showEmotesTab)
Expand All @@ -404,4 +355,73 @@ class _ChatState extends State<Chat> {
],
);
}

SizedBox _buildRewindMenu(ChatModel chat) {
return SizedBox(
height: 60,
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.min,
children: [
for (final time in rewindOptions)
Expanded(
child: TextButton(
style: TextButton.styleFrom(
// primary: Theme.of(context).rewindButton,
padding: EdgeInsets.zero,
),
child: Align(
alignment: Alignment.center,
child: Text(time.toString(), maxLines: 1),
),
onPressed: () {
chat.sendMessage('/$time');
setState(() => showRewindMenu = false);
},
),
),
],
),
);
}

GestureDetector _buildEmotesButton(BuildContext context) {
return GestureDetector(
onLongPress: () {
HapticFeedback.mediumImpact();
setState(() => showRewindMenu = !showRewindMenu);
},
child: Padding(
padding: const EdgeInsets.all(5),
child: IconButton(
onPressed: () {
if (showRewindMenu) {
setState(() => showRewindMenu = false);
return;
}
setState(() {
showEmotesTab = !showEmotesTab;
if (showEmotesTab) {
reopenKeyboard = inputFocus.hasFocus;
inputFocus.unfocus();
} else {
if (reopenKeyboard && textController.text.isNotEmpty)
inputFocus.requestFocus();
reopenKeyboard = false;
}
});
SystemChrome.restoreSystemUIOverlays();
},
icon: Icon(
showRewindMenu ? Icons.close : Icons.mood,
size: 35,
color: showEmotesTab
? Theme.of(context).colorScheme.primary
: Theme.of(context).icon,
),
),
),
);
}
}
54 changes: 30 additions & 24 deletions lib/chat_panel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,10 @@ class ChatPanel extends StatelessWidget {
),
),
const Spacer(flex: 2),
TextButton(
onPressed: () => showUsersSnackBar(context),
style: ButtonStyle(
padding: WidgetStateProperty.all(
EdgeInsets.symmetric(horizontal: 5, vertical: 5),
),
),
Flexible(
flex: 100,
child: _onlineButton(panel, context),
),
const Spacer(flex: 100),
leaderButton(panel, context, parentW),
const Spacer(flex: 5),
IconButton(
Expand Down Expand Up @@ -119,23 +113,35 @@ class ChatPanel extends StatelessWidget {
}

Widget _onlineButton(ChatPanelModel panel, BuildContext context) {
final isPlayerIconVisible = !panel.serverPlay || panel.hasLeader();
return Row(
children: [
Text(
!panel.isConnected
? 'Connection...'
: '${panel.clients.length} online',
style: TextStyle(color: Theme.of(context).icon),
final isPlayerIconVisible = panel.lastState.paused || panel.hasLeader();
final clientsOnlineText = !panel.isConnected
? 'Connection...'
: '${panel.clients.length} online';

return TextButton(
onPressed: () => showUsersSnackBar(context),
style: ButtonStyle(
padding: WidgetStateProperty.all(
EdgeInsets.symmetric(horizontal: 5, vertical: 5),
),
if (isPlayerIconVisible)
Icon(
panel.serverPlay ? Icons.play_arrow : Icons.pause,
color: Theme.of(context).icon,
)
else
const Text(' '),
],
),
child: Row(
children: [
Flexible(
child: Text(
clientsOnlineText,
style: TextStyle(color: Theme.of(context).icon),
overflow: .ellipsis,
maxLines: 1,
),
),
if (isPlayerIconVisible)
Icon(
panel.lastState.paused ? Icons.pause : Icons.play_arrow,
color: Theme.of(context).icon,
),
],
),
);
}
}
Loading