Skip to content

Instantly share code, notes, and snippets.

@insin
Last active May 3, 2022 11:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save insin/8859c7816123e546c927dda04359c9d8 to your computer and use it in GitHub Desktop.
Save insin/8859c7816123e546c927dda04359c9d8 to your computer and use it in GitHub Desktop.
Remote Control for VLC Configuration Guides
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.deepOrange,
),
home: Scaffold(
appBar: AppBar(
centerTitle: true,
title: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: const <Widget>[
Text('Remote Control for VLC Configuration Guides'),
],
),
),
body: Builder(
builder: (context) => Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
'What would you like help with?',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.deepOrange,
onPrimary : Colors.white,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const VlcConfigurationGuide()));
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: const <Widget>[
Icon(Icons.traffic),
SizedBox(width: 8.0),
Text('Configuring VLC for remote control'),
],
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.deepOrange,
onPrimary : Colors.white,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const HostIpGuide()));
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: const <Widget>[
Icon(Icons.help),
SizedBox(width: 8.0),
Text('Finding my Host IP'),
],
),
)
],
),
),
),
),
),
);
}
enum OperatingSystem { linux, macos, windows }
Map<OperatingSystem, String> osNames = {
OperatingSystem.linux: 'Linux',
OperatingSystem.macos: 'macOS',
OperatingSystem.windows: 'Windows',
};
class VlcConfigurationGuide extends StatefulWidget {
const VlcConfigurationGuide({Key? key}) : super(key: key);
@override
_VlcConfigurationGuideState createState() => _VlcConfigurationGuideState();
}
class _VlcConfigurationGuideState extends State<VlcConfigurationGuide> {
int _currentStep = 0;
OperatingSystem? _os;
_onOsChanged(os) {
setState(() {
_os = os;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
const Text('VLC Configuration Guide'),
if (_os != null)
Text('for ${osNames[_os]}', style: const TextStyle(fontSize: 13)),
],
),
),
body: buildBody(),
);
}
Widget buildBody() {
switch (_os) {
case OperatingSystem.macos:
return buildMacStepper();
case OperatingSystem.linux:
case OperatingSystem.windows:
return buildLinuxWindowsStepper();
default:
var theme = Theme.of(context);
return Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(24),
child: Wrap(
runSpacing: 16,
children: [
Text('Which operating system are you running VLC on?',
style: theme.textTheme.subtitle1),
Column(
children: OperatingSystem.values
.map((os) => RadioListTile(
title: Text(osNames[os]!),
value: os,
groupValue: _os,
onChanged: _onOsChanged,
))
.toList())
],
),
),
],
);
}
}
Widget buildLinuxWindowsStepper() {
var theme = Theme.of(context);
var os = _os.toString().split('.').last;
return Stepper(
currentStep: _currentStep,
controlsBuilder: (BuildContext context, ControlsDetails details) {
return Padding(
padding: const EdgeInsets.only(top: 16),
child: Row(
children: <Widget>[
TextButton(
style: TextButton.styleFrom(
backgroundColor: theme.primaryColor,
primary: Colors.white,
),
onPressed: details.onStepContinue,
child: Text(_currentStep == 2 ? 'FINISHED' : 'NEXT STEP'),
),
TextButton(
onPressed: details.onStepCancel,
child: const Text('PREVIOUS STEP'),
),
],
),
);
},
onStepCancel: () {
if (_currentStep > 0) {
setState(() {
_currentStep--;
});
} else {
_onOsChanged(null);
}
},
onStepContinue: () {
if (_currentStep == 2) {
Navigator.pop(context);
return;
}
setState(() {
_currentStep++;
});
},
steps: [
Step(
title: const Text('Enable VLC\'s web interface'),
content: TextAndImages(
children: <Widget>[
const Text(
'In VLC\'s menu bar, select Tools > Preferences to open the preferences window:'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/$os-menu.png'),
const Text(
'Switch to Advanced Preferences mode by clicking the "All" radio button in the "Show settings" section at the bottom left of the window:'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/$os-show-settings.png'),
const Text(
'Scroll down to find the "Main interfaces" section and click it:'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/$os-main-interface.png'),
const Text(
'Check the "Web" checkbox in the "Extra interface modules" section to enable the web interface:'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/$os-web.png'),
],
),
),
Step(
title: const Text('Set web interface password'),
content: TextAndImages(
children: <Widget>[
const Text(
'Expand the "Main interfaces" section by clicking the ">" chevron and click the "Lua" section which appears:'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/$os-lua.png'),
const Text('Set a password in the "Lua HTTP" section:'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/$os-password.png'),
const Text(
'Remote Control for VLC uses the password "vlcplayer" (without quotes) by default – if you set something else you\'ll have to manually configure the VLC connection.'),
const Text('Finally, click Save to save your changes.'),
],
),
),
Step(
title: const Text('Close and restart VLC'),
content: Row(
children: const <Widget>[
Text('Close and restart VLC to activate the web interface.'),
],
),
)
],
);
}
Widget buildMacStepper() {
var theme = Theme.of(context);
return Stepper(
currentStep: _currentStep,
controlsBuilder: (BuildContext context, ControlsDetails details) {
return Padding(
padding: const EdgeInsets.only(top: 16),
child: Row(
children: <Widget>[
TextButton(
style: TextButton.styleFrom(
backgroundColor: theme.primaryColor,
primary: Colors.white,
),
onPressed: details.onStepContinue,
child: Text(_currentStep == 1 ? 'FINISHED' : 'NEXT STEP'),
),
TextButton(
onPressed: details.onStepCancel,
child: const Text('PREVIOUS STEP'),
),
],
),
);
},
onStepCancel: () {
if (_currentStep > 0) {
setState(() {
_currentStep--;
});
} else {
_onOsChanged(null);
}
},
onStepContinue: () {
if (_currentStep == 1) {
Navigator.pop(context);
return;
}
setState(() {
_currentStep++;
});
},
steps: [
Step(
title: const Text('Enable VLC\'s web interface'),
content: TextAndImages(
children: <Widget>[
const Text(
'In the Menubar, select VLC > Preferences to open the preferences window:'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/mac-menu.png'),
const Text(
'At the bottom of the "Interface" settings page, check "Enable HTTP web interface" and set a password.'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/mac-http-interface.png'),
const Text(
'Remote Control for VLC uses the password "vlcplayer" (without quotes) by default – if you set something else you\'ll have to manually configure the VLC connection.'),
const Text('Finally, click Save to save your changes.'),
],
),
),
Step(
title: const Text('Quit and restart VLC'),
content: Row(
children: const <Widget>[
Text('Quit and restart VLC to activate the web interface.'),
],
),
)
],
);
}
}
class HostIpGuide extends StatefulWidget {
const HostIpGuide({Key? key}) : super(key: key);
@override
_HostIpGuideState createState() => _HostIpGuideState();
}
class _HostIpGuideState extends State<HostIpGuide> {
OperatingSystem? _os;
_onOsChanged(os) {
setState(() {
_os = os;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
const Text('Host IP Guide'),
if (_os != null)
Text('for ${osNames[_os]}', style: const TextStyle(fontSize: 13)),
],
),
),
body: buildBody(),
);
}
Widget buildBody() {
var theme = Theme.of(context);
switch (_os) {
case OperatingSystem.macos:
return ListView(padding: const EdgeInsets.all(24), children: [
TextAndImages(children: <Widget>[
const Text('From the Apple menu, select "System Preferences".'),
const Text(
'In the System Preferences window, click on the "Network" item:'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/mac-network.png'),
const Text(
'Your IP address will be visible to the right of the Network window, as shown below:'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/mac-ip.png'),
]),
]);
case OperatingSystem.linux:
return ListView(padding: const EdgeInsets.all(24), children: [
TextAndImages(children: <Widget>[
const Text(
'Open a Terminal – on many popular distros this can be done by pressing Ctr + Alt + T.'),
const Text(
'In the Terminal window, type "ifconfig" and press Enter:'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/linux-terminal.png'),
const Text(
'Your host IP will be one of the "inet" IP results which appears in the output of the command:'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/linux-ifconfig.png'),
const Text(
'Depending on how your computer is set up, there may be multiple results:'),
const Text(
'If you connect to the network via an ethernet cable, look for the inet IP under an "eth0" interface.'),
const Text(
'If you connect to the network via Wi-Fi, look for the inet IP under a "wlan0" interface.'),
]),
]);
case OperatingSystem.windows:
return ListView(padding: const EdgeInsets.all(24), children: [
TextAndImages(children: <Widget>[
const Text(
'Open a Command Prompt by pressing Win + R, typing "cmd" in the dialog which appears, and presssing Enter:'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/windows-run.png'),
const Text(
'In the Command Prompt window, type "ipconfig" and press Enter:'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/windows-cmd.png'),
const Text(
'Your host IP will be one of the "IPv4 Address" results which appears in the output of the command:'),
Image.network(
'https://raw.githubusercontent.com/insin/remote_control_for_vlc/master/assets/windows-ipconfig.png'),
const Text(
'Depending on how your computer is set up, there may be multiple results:'),
const Text(
'If you connect to the network via an ethernet cable, look for the IPv4 Address under an "Ethernet adapter Ethernet" result.'),
const Text(
'If you connect to the network via Wi-Fi, look for the IPv4 Address under an "Ethernet adapter Wireless Network Connection" result.'),
]),
]);
default:
return Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(24),
child: Wrap(
runSpacing: 16,
children: [
Text('Which operating system are you running VLC on?',
style: theme.textTheme.subtitle1),
Column(
children: OperatingSystem.values
.map((os) => RadioListTile(
title: Text(osNames[os]!),
value: os,
groupValue: _os,
onChanged: _onOsChanged,
))
.toList())
],
),
),
],
);
}
}
}
/// Like [Iterable.join] but for lists of Widgets.
Iterable<Widget> intersperseWidgets(Iterable<Widget> iterable,
{required Widget Function() builder}) sync* {
final iterator = iterable.iterator;
if (iterator.moveNext()) {
yield iterator.current;
while (iterator.moveNext()) {
yield builder();
yield iterator.current;
}
}
}
class TextAndImages extends StatelessWidget {
final List<Widget> children;
final double spacing;
const TextAndImages({Key? key, required this.children, this.spacing = 16})
: super(key: key);
@override
Widget build(BuildContext context) {
return Column(
children: intersperseWidgets(
children.map((child) => Row(children: [
Expanded(
child: Container(
alignment: Alignment.topLeft,
child: child,
))
])),
builder: () => SizedBox(height: spacing),
).toList(),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment