Membuat Aplikasi Dengan Fitur Kirim Pesan Via Whatsaap - Dart Flutter
Membuat Aplikasi Dengan Fitur Kirim Pesan Via Whatsaap - Dart Flutter
Dokumentasi Teknis: Pengembangan Aplikasi "Liquid Send" dengan Flutter
1. Pendahuluan
2. Arsitektur Kode dan Library
3. Analisis Function Utama
Aplikasi Liquid Send adalah alat bantu produktivitas yang memungkinkan pengguna mengirim pesan WhatsApp tanpa harus menyimpan nomor tujuan ke buku telepon. Fokus utama project ini adalah penggabungan fungsionalitas URL Launcher dengan tren desain Glassmorphism.
Aplikasi Liquid Send adalah alat bantu produktivitas yang memungkinkan pengguna mengirim pesan WhatsApp tanpa harus menyimpan nomor tujuan ke buku telepon. Fokus utama project ini adalah penggabungan fungsionalitas URL Launcher dengan tren desain Glassmorphism.
Pada project ini, kita menggunakan Flutter Web (DartPad). Library utama yang digunakan adalah:
material.dart: Untuk komponen UI standar.
dart:html: Untuk berinteraksi dengan browser (membuka tab baru).
dart:ui: Untuk mengakses filter grafis seperti Blur.
Pada project ini, kita menggunakan Flutter Web (DartPad). Library utama yang digunakan adalah:
material.dart: Untuk komponen UI standar.dart:html: Untuk berinteraksi dengan browser (membuka tab baru).dart:ui: Untuk mengakses filter grafis seperti Blur.
Bagian paling krusial adalah fungsi kirimPesan(). Berikut adalah bedah logikanya:
Dartvoid kirimPesan() {
String nomor = _nomorController.text;
String pesan = _pesanController.text;
// Logika Normalisasi Nomor
if (nomor.startsWith('0')) {
nomor = '62${nomor.substring(1)}';
}
// Logika URL Encoding
String pesanEncoded = Uri.encodeComponent(pesan);
// Konstruksi URL API WhatsApp
String url = "https://wa.me/$nomor?text=$pesanEncoded";
// Eksekusi pada Browser
html.window.open(url, '_blank');
}
Bagian paling krusial adalah fungsi kirimPesan(). Berikut adalah bedah logikanya:
void kirimPesan() {
String nomor = _nomorController.text;
String pesan = _pesanController.text;
// Logika Normalisasi Nomor
if (nomor.startsWith('0')) {
nomor = '62${nomor.substring(1)}';
}
// Logika URL Encoding
String pesanEncoded = Uri.encodeComponent(pesan);
// Konstruksi URL API WhatsApp
String url = "https://wa.me/$nomor?text=$pesanEncoded";
// Eksekusi pada Browser
html.window.open(url, '_blank');
}
Penjelasan Logika:
- Normalisasi Nomor: WhatsApp API membutuhkan kode negara (62 untuk Indonesia). Fungsi ini mendeteksi jika user mengetik
08..., lalu membuang angka 0 dan menggantinya dengan 62.
- URI Encoding: Karakter seperti spasi, tanda tanya, atau simbol diubah menjadi format yang dimengerti URL (contoh: spasi menjadi
%20). Tanpa ini, link akan rusak saat diklik.
html.window.open: Karena berjalan di web, kita memerintahkan browser membuka tab baru yang akan memicu aplikasi WhatsApp di perangkat user.
- Normalisasi Nomor: WhatsApp API membutuhkan kode negara (62 untuk Indonesia). Fungsi ini mendeteksi jika user mengetik
08..., lalu membuang angka0dan menggantinya dengan62.
- URI Encoding: Karakter seperti spasi, tanda tanya, atau simbol diubah menjadi format yang dimengerti URL (contoh: spasi menjadi
%20). Tanpa ini, link akan rusak saat diklik.
html.window.open: Karena berjalan di web, kita memerintahkan browser membuka tab baru yang akan memicu aplikasi WhatsApp di perangkat user.
4. Desain UI: Liquid Glassmorphism
Efek "Kaca Cair" dicapai melalui teknik layering (berlapis):
Background Layer: Menggunakan LinearGradient dengan warna cerah untuk menciptakan kontras.
Blur Layer: Menggunakan widget BackdropFilter dengan ImageFilter.blur(sigmaX: 15, sigmaY: 15). Ini yang menciptakan efek buram transparan.
Border Layer: Garis tepi putih tipis dengan opasitas rendah (Colors.white.withOpacity(0.3)) untuk memberikan efek pantulan cahaya di pinggiran kaca.
Efek "Kaca Cair" dicapai melalui teknik layering (berlapis):
Background Layer: Menggunakan
LinearGradientdengan warna cerah untuk menciptakan kontras.Blur Layer: Menggunakan widget
BackdropFilterdenganImageFilter.blur(sigmaX: 15, sigmaY: 15). Ini yang menciptakan efek buram transparan.Border Layer: Garis tepi putih tipis dengan opasitas rendah (
Colors.white.withOpacity(0.3)) untuk memberikan efek pantulan cahaya di pinggiran kaca.
5. Implementasi Kode Lengkap
Berikut adalah kode utuh yang menggabungkan semua fungsi dan desain di atas:
Dart// KODE SUMBER UTAMA (DART)
import 'package:flutter/material.dart';
import 'dart:html' as html;
import 'dart:ui';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: const GlassMessagingPage(),
);
}
}
// Widget Stateful untuk menangani input user
class GlassMessagingPage extends StatefulWidget {
const GlassMessagingPage({super.key});
@override
State<GlassMessagingPage> createState() => _GlassMessagingPageState();
}
class _GlassMessagingPageState extends State<GlassMessagingPage> {
final TextEditingController _nomorController = TextEditingController();
final TextEditingController _pesanController = TextEditingController();
// Implementasi Function Kirim
void kirimPesan() {
String nomor = _nomorController.text;
String pesan = _pesanController.text;
if (nomor.startsWith('0')) nomor = '62${nomor.substring(1)}';
String url = "https://wa.me/$nomor?text=${Uri.encodeComponent(pesan)}";
html.window.open(url, '_blank');
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF6AC1B8), Color(0xFF4568DC), Color(0xFFB06AB3)],
),
),
child: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(30),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15),
child: Container(
width: 350,
padding: const EdgeInsets.all(25),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
borderRadius: BorderRadius.circular(30),
border: Border.all(color: Colors.white.withOpacity(0.2)),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text("Liquid Send", style: TextStyle(color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 30),
// Input Fields menggunakan helper widget
_inputField(_nomorController, "Nomor WA", Icons.phone),
const SizedBox(height: 15),
_inputField(_pesanController, "Isi Pesan", Icons.message, maxLines: 3),
const SizedBox(height: 30),
ElevatedButton(
onPressed: kirimPesan,
style: ElevatedButton.styleFrom(backgroundColor: Colors.white),
child: const Text("KIRIM PESAN", style: TextStyle(color: Colors.indigo)),
)
],
),
),
),
),
),
),
);
}
Widget _inputField(TextEditingController ctrl, String hint, IconData icon, {int maxLines = 1}) {
return TextField(
controller: ctrl,
maxLines: maxLines,
style: const TextStyle(color: Colors.white),
decoration: InputDecoration(
prefixIcon: Icon(icon, color: Colors.white70),
hintText: hint,
hintStyle: const TextStyle(color: Colors.white54),
filled: true,
fillColor: Colors.white.withOpacity(0.05),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(15)),
),
);
}
}
Berikut adalah kode utuh yang menggabungkan semua fungsi dan desain di atas:
// KODE SUMBER UTAMA (DART)
import 'package:flutter/material.dart';
import 'dart:html' as html;
import 'dart:ui';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: const GlassMessagingPage(),
);
}
}
// Widget Stateful untuk menangani input user
class GlassMessagingPage extends StatefulWidget {
const GlassMessagingPage({super.key});
@override
State<GlassMessagingPage> createState() => _GlassMessagingPageState();
}
class _GlassMessagingPageState extends State<GlassMessagingPage> {
final TextEditingController _nomorController = TextEditingController();
final TextEditingController _pesanController = TextEditingController();
// Implementasi Function Kirim
void kirimPesan() {
String nomor = _nomorController.text;
String pesan = _pesanController.text;
if (nomor.startsWith('0')) nomor = '62${nomor.substring(1)}';
String url = "https://wa.me/$nomor?text=${Uri.encodeComponent(pesan)}";
html.window.open(url, '_blank');
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF6AC1B8), Color(0xFF4568DC), Color(0xFFB06AB3)],
),
),
child: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(30),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 15, sigmaY: 15),
child: Container(
width: 350,
padding: const EdgeInsets.all(25),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
borderRadius: BorderRadius.circular(30),
border: Border.all(color: Colors.white.withOpacity(0.2)),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text("Liquid Send", style: TextStyle(color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold)),
const SizedBox(height: 30),
// Input Fields menggunakan helper widget
_inputField(_nomorController, "Nomor WA", Icons.phone),
const SizedBox(height: 15),
_inputField(_pesanController, "Isi Pesan", Icons.message, maxLines: 3),
const SizedBox(height: 30),
ElevatedButton(
onPressed: kirimPesan,
style: ElevatedButton.styleFrom(backgroundColor: Colors.white),
child: const Text("KIRIM PESAN", style: TextStyle(color: Colors.indigo)),
)
],
),
),
),
),
),
),
);
}
Widget _inputField(TextEditingController ctrl, String hint, IconData icon, {int maxLines = 1}) {
return TextField(
controller: ctrl,
maxLines: maxLines,
style: const TextStyle(color: Colors.white),
decoration: InputDecoration(
prefixIcon: Icon(icon, color: Colors.white70),
hintText: hint,
hintStyle: const TextStyle(color: Colors.white54),
filled: true,
fillColor: Colors.white.withOpacity(0.05),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(15)),
),
);
}
}
6. Kesimpulan
Aplikasi ini berhasil menunjukkan bahwa dengan baris kode yang minimal, kita dapat menciptakan solusi yang fungsional dan estetis. Penggunaan Uri.encodeComponent menjadi kunci utama keamanan data pesan, sementara BackdropFilter menjadi kunci keindahan antarmuka.
Aplikasi ini berhasil menunjukkan bahwa dengan baris kode yang minimal, kita dapat menciptakan solusi yang fungsional dan estetis. Penggunaan Uri.encodeComponent menjadi kunci utama keamanan data pesan, sementara BackdropFilter menjadi kunci keindahan antarmuka.
Komentar
Posting Komentar