Replace 'flutter pub get' with 'flutter pub add' for url_launcher in … #10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Flutter Web Preview Build | |
# . Before you push to main, you need to create a new branch named live_preview | |
# . Then go to Sttings> Pages and select the live_preview branch as the source and the /(docs) directory. | |
# . Then, you need to create a new workflow file named deploy_live_preview.yml in the .github/workflows directory. | |
# . Add the following code to the deploy_live_preview.yml file: | |
on: | |
push: | |
branches: [master] #. Specify the main/master branch name | |
permissions: | |
contents: write | |
jobs: | |
build: | |
runs-on: ubuntu-latest | |
env: | |
API_KEY: ${{ secrets.API_KEY }} | |
CONTEXT_KEY: ${{ secrets.CONTEXT_KEY }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
token: ${{ secrets.GITHUB_TOKEN }} | |
fetch-depth: 0 | |
- name: Reset live_preview branch to master | |
run: | | |
# Create or checkout live_preview branch | |
git checkout live_preview 2>/dev/null || git checkout -b live_preview | |
# Force reset to master branch state | |
git fetch origin master | |
git reset --hard origin/master | |
# Force push to update live_preview branch | |
git push -f origin live_preview | |
- name: Set up Flutter | |
uses: subosito/flutter-action@v2 | |
with: | |
flutter-version: "3.24.4" #. Specify the Flutter version | |
channel: "stable" | |
- name: Install dependencies | |
run: | | |
flutter clean | |
flutter pub get | |
flutter pub add device_preview | |
flutter pub add device_preview_screenshot | |
flutter pub add font_awesome_flutter | |
flutter pub add url_launcher | |
flutter pub get | |
- name: Update device_preview_button.dart for preview | |
run: | | |
# Ensure we're creating a fresh main.dart | |
cat > lib/device_preview_button.dart << 'EOL' | |
import 'package:device_preview/device_preview.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:font_awesome_flutter/font_awesome_flutter.dart'; | |
import 'package:url_launcher/url_launcher.dart'; | |
class CustomPlugin extends StatelessWidget { | |
final String authorDescription; | |
final String? sourceCodeUrl; | |
final String? apkDownloadUrl; | |
final Color themeColor; | |
const CustomPlugin({ | |
super.key, | |
this.authorDescription = "Flutter Developer", | |
this.sourceCodeUrl, | |
this.apkDownloadUrl, | |
this.themeColor = const Color(0xFF2196F3), | |
}); | |
@override | |
Widget build(BuildContext context) { | |
return ToolPanelSection( | |
title: 'Auther and Project INFO', | |
children: [ | |
Container( | |
decoration: BoxDecoration( | |
color: themeColor.withOpacity(0.05), | |
borderRadius: BorderRadius.circular(12), | |
), | |
child: Column( | |
children: [ | |
_buildAuthorSection(), | |
_buildActionSection(), | |
], | |
), | |
), | |
], | |
); | |
} | |
Widget _buildActionButton({ | |
required IconData icon, | |
required String label, | |
required VoidCallback onPressed, | |
bool isPrimary = false, | |
}) { | |
return ElevatedButton( | |
onPressed: onPressed, | |
style: ElevatedButton.styleFrom( | |
backgroundColor: isPrimary ? themeColor : themeColor.withOpacity(0.1), | |
foregroundColor: isPrimary ? Colors.white : themeColor, | |
padding: const EdgeInsets.symmetric(horizontal: 16,vertical: 12), | |
shape: RoundedRectangleBorder( | |
borderRadius: BorderRadius.circular(8), | |
), | |
elevation: isPrimary ? 2 : 0, | |
), | |
child: Row( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
Icon( | |
icon, | |
size: 20, | |
color: isPrimary ? Colors.white : themeColor, | |
), | |
const SizedBox(width: 8), | |
Text( | |
label, | |
style: const TextStyle( | |
fontSize: 14, | |
fontWeight: FontWeight.w600, | |
), | |
), | |
], | |
), | |
); | |
} | |
Widget _buildActionSection() { | |
return Container( | |
padding: const EdgeInsets.all(16), | |
child: Row( | |
children: [ | |
if (sourceCodeUrl != null) | |
Expanded( | |
child: _buildActionButton( | |
icon: Icons.code, | |
label: 'Source Code', | |
onPressed: () => _launchUrl(sourceCodeUrl!), | |
), | |
), | |
if (sourceCodeUrl != null && apkDownloadUrl != null) | |
const SizedBox(width: 12), | |
if (apkDownloadUrl != null) | |
Expanded( | |
child: _buildActionButton( | |
icon: Icons.download, | |
label: 'Download APK', | |
onPressed: () => _launchUrl(apkDownloadUrl!), | |
isPrimary: true, | |
), | |
), | |
], | |
), | |
); | |
} | |
Widget _buildAuthorSection() { | |
return Container( | |
padding: const EdgeInsets.all(16), | |
decoration: BoxDecoration( | |
color: themeColor.withOpacity(0.1), | |
borderRadius: const BorderRadius.only( | |
topLeft: Radius.circular(12), | |
topRight: Radius.circular(12), | |
), | |
), | |
child: Column( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
Row( | |
children: [ | |
CircleAvatar( | |
backgroundColor: themeColor, | |
radius: 24, | |
child: const Text( | |
'HK', | |
style: TextStyle( | |
color: Colors.white, | |
fontWeight: FontWeight.bold, | |
), | |
), | |
), | |
const SizedBox(width: 12), | |
Expanded( | |
child: Column( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
Text( | |
'Harshit Khandelwal', | |
style: TextStyle( | |
fontSize: 18, | |
fontWeight: FontWeight.bold, | |
color: themeColor, | |
), | |
), | |
Text( | |
authorDescription, | |
style: TextStyle( | |
fontSize: 14, | |
color: Colors.grey[600], | |
), | |
), | |
], | |
), | |
), | |
], | |
), | |
const SizedBox(height: 16), | |
_buildSocialButtons(), | |
], | |
), | |
); | |
} | |
Widget _buildSocialButtons() { | |
return Wrap( | |
spacing: 8, | |
runSpacing: 8, | |
alignment: WrapAlignment.center, | |
children: [ | |
_buildSocialLink( | |
icon: FontAwesomeIcons.globe, | |
label: 'Portfolio', | |
url: 'https://harshit2756.github.io/portfolio/', | |
), | |
_buildSocialLink( | |
icon: FontAwesomeIcons.github, | |
label: 'GitHub', | |
url: 'https://github.com/Harshit2756', | |
), | |
_buildSocialLink( | |
icon: FontAwesomeIcons.twitter, | |
label: 'Twitter', | |
url: 'https://twitter.com/Harshit2756', | |
), | |
_buildSocialLink( | |
icon: FontAwesomeIcons.linkedin, | |
label: 'LinkedIn', | |
url: 'https://www.linkedin.com/in/harshit-khandelwal-3a76631b9/', | |
), | |
_buildSocialLink( | |
icon: FontAwesomeIcons.medium, | |
label: 'Medium', | |
url: 'https://medium.com/@Harshit2756', | |
), | |
], | |
); | |
} | |
Widget _buildSocialLink({ | |
required IconData icon, | |
required String label, | |
required String url, | |
}) { | |
return Tooltip( | |
message: label, | |
child: InkWell( | |
onTap: () => _launchUrl(url), | |
borderRadius: BorderRadius.circular(8), | |
child: Container( | |
padding: const EdgeInsets.symmetric( | |
horizontal: 12, | |
vertical: 8, | |
), | |
child: Row( | |
mainAxisSize: MainAxisSize.min, | |
children: [ | |
FaIcon( | |
icon, | |
size: 18, | |
color: themeColor, | |
), | |
const SizedBox(width: 8), | |
Text( | |
label, | |
style: TextStyle( | |
color: themeColor, | |
fontSize: 14, | |
), | |
), | |
], | |
), | |
), | |
), | |
); | |
} | |
Future<void> _launchUrl(String url) async { | |
if (!await launchUrl(Uri.parse(url))) { | |
throw Exception('Could not launch $url'); | |
} | |
} | |
} | |
EOL | |
- name: Create .env file | |
run: | | |
cat > lib/config/api_keys.env << EOL | |
API_KEY=${{ secrets.API_KEY }} | |
CONTEXT_KEY=${{ secrets.CONTEXT_KEY }} | |
EOL | |
- name: Update main.dart for preview | |
run: | | |
# Ensure we're creating a fresh main.dart | |
cat > lib/main.dart << 'EOL' #. Replace with your main.dart content | |
import 'dart:io'; | |
import 'package:device_preview_screenshot/device_preview_screenshot.dart'; | |
import 'package:device_preview/device_preview.dart'; | |
import 'device_preview_button.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:google_clone/colors.dart'; | |
import 'package:flutter_dotenv/flutter_dotenv.dart'; | |
import 'package:google_clone/responsive/mobile_screen_layout.dart'; | |
import 'package:google_clone/responsive/responsive_layout_screen.dart'; | |
import 'package:google_clone/responsive/web_screen_layout.dart'; | |
void main() async { | |
try { | |
// Try multiple paths | |
await dotenv.load(fileName: "lib/config/api_keys.env"); | |
} catch (e) { | |
print("Failed to load .env file, using environment variables"); | |
// Fallback to environment variables | |
dotenv.env['API_KEY'] = Platform.environment['API_KEY'] ?? ''; | |
dotenv.env['CONTEXT_KEY'] = Platform.environment['CONTEXT_KEY'] ?? ''; | |
} | |
runApp( | |
DevicePreview( | |
// backgroundColor: , | |
tools: const [ | |
CustomPlugin( | |
apkDownloadUrl: "https://github.com/${{ github.repository }}/releases/download/v1.0.0/app-release.apk", | |
sourceCodeUrl: "https://github.com/${{ github.repository }}/archive/refs/tags/v1.0.0.zip", | |
), | |
DeviceSection( | |
frameVisibility: true, | |
orientation: false, | |
), | |
// SystemSection( | |
// locale: false, | |
// theme: true, | |
// ), | |
// AccessibilitySection( | |
// accessibleNavigation: false, | |
// boldText: false, | |
// invertColors: false, | |
// textScalingFactor: false, | |
// ), | |
DevicePreviewScreenshot(), | |
SettingsSection(), | |
], | |
defaultDevice: Devices.ios.iPhone13ProMax, | |
enabled: true, | |
builder: (context) => const MyApp(), | |
), | |
); | |
} | |
class MyApp extends StatelessWidget { | |
const MyApp({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
locale: DevicePreview.locale(context), | |
builder: DevicePreview.appBuilder, | |
debugShowCheckedModeBanner: false, | |
theme: ThemeData.dark().copyWith( | |
scaffoldBackgroundColor: backgroundColor, | |
tooltipTheme: TooltipThemeData( | |
waitDuration: const Duration(seconds: 1), | |
textStyle: const TextStyle( | |
color: Colors.white, | |
fontSize: 14, | |
fontWeight: FontWeight.w400, | |
), | |
decoration: BoxDecoration( | |
color: const Color(0xff424548), | |
borderRadius: BorderRadius.circular(4), | |
), | |
), | |
), | |
title: 'Google Clone', | |
home: const ResposiveLayoutScreen( | |
mobileScreenLayout: MobileScreenLayout(), | |
webScreenLayout: WebScreenLayout(), | |
), | |
); | |
} | |
} | |
EOL | |
- name: Build Web | |
run: | | |
flutter build web | |
# cat build/web/index.html | grep "base href" | |
- name: Update docs directory | |
run: | | |
# Remove old docs and create new one | |
rm -rf docs | |
mkdir -p docs | |
# Copy web build to docs | |
cp -r build/web/. docs/ | |
- name: Commit and push preview changes | |
run: | | |
git config --global user.name 'github-actions[bot]' | |
git config --global user.email 'github-actions[bot]@users.noreply.github.com' | |
# Stage all changes | |
git add docs lib/main.dart | |
git commit -m "Update web preview build" || echo "No changes to commit" | |
# Force push to ensure clean state | |
git push -f origin live_preview |