"matchMedia" support in Dart - media-queries

How to use window.matchMedia in Dart?
I have found corresponding method:
MediaQueryList matchMedia(String query)
And "MediaQueryList" method:
void addListener(MediaQueryListListener listener)
But: MediaQueryListListener has no constructor and looks like some sort of a generated stub.
I have JS example:
var mq = window.matchMedia( "(min-width: 500px)" );
// media query event handler
if (matchMedia) {
var mq = window.matchMedia("(min-width: 500px)");
mq.addListener(WidthChange);
WidthChange(mq);
}
// media query change
function WidthChange(mq) {
if (mq.matches) {
// window width is at least 500px
}
else {
// window width is less than 500px
}
}
And it has good support http://caniuse.com/#feat=matchmedia

As pointed in a comment it doesn't seem to be implemented in Dart for now.
However you can use dart:js to do that like this :
import 'dart:js';
main() {
if (context['matchMedia'] != null) {
final mq = context.callMethod('matchMedia', ['(min-width: 500px)']);
mq.callMethod('addListener', [widthChange]);
widthChange(mq);
}
}
widthChange(mq) {
if (mq['matches']) {
print('window width is at least 500px');
} else {
print('window width is less than 500px');
}
}

Related

SwiftUI : How I can set refreshable for my Scrollview without List

import SwiftUI
struct HomeView: View {
#StateObject var vm = NewsViewModel()
let dataService = NewsDataService.instance
init() {
dataService.apiCall(text: "Korea")
}
var body: some View {
NavigationView {
ScrollView(.vertical, showsIndicators: false) {
SearchView()
VStack {
Divider()
if let newsArray = vm.newsArray?.articles {
ForEach(newsArray) { news in
NewsRowView(news: news)
}
}
}
}
.navigationTitle("News")
.navigationBarTitleDisplayMode(.automatic)
}
}
}
struct HomeView_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
Hi, I tried to find refresh for my scrollview.
But, most of the examples were capable with List.
As you can see my code, I makde my list with HStack children View.
Because of that, I can't use the ".refreshable" modifier.
So, I want to know how I can set that in my view.
And If I can, I want to see detailed code as well!
Thanks.
You could use refreshable like this in your NewsRowView. Keep in mind you would need to make sure you are using ObservableObject where necessary so that it will give you the new data once it's updated.
.refreshable {
Task {
let dataService = NewsDataService.instance
dataService.apiCall(text: "Korea")
}
}

Pass API Data to GetX Controller from class

How can I pass the decoded Data from my Api to my GetX Controller?
Here is my Class "Germany" and my fetchGermany() Function.
Future<Germany> fetchGermany() async {
final response =
await get(Uri.parse('https://api.corona-zahlen.org/germany'));
if (response.statusCode == 200) {
return Germany.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to get data');
}
}
class Germany {
int cases;
int deaths;
int recovered;
double weekIncidence;
double casesPer100k;
int casesPerWeek;
Germany(
{required this.cases,
required this.deaths,
required this.recovered,
required this.weekIncidence,
required this.casesPer100k,
required this.casesPerWeek});
factory Germany.fromJson(Map<String, dynamic> json) {
return Germany(
cases: json["cases"],
deaths: json["deaths"],
recovered: json["recovered"],
weekIncidence: json["weekIncidence"],
casesPer100k: json["casesPer100k"],
casesPerWeek: json["casesPerWeek"]);
}
}
Here is my GetX controller which is empty at the moment:
class DetailController extends GetxController {
}
So basically I just want to be able to acceess this data:
cases: json["cases"],
deaths: json["deaths"],
recovered: json["recovered"],
weekIncidence: json["weekIncidence"],
casesPer100k: json["casesPer100k"],
casesPerWeek: json["casesPerWeek"]
While I agree with #DarShan that you don't necessarily need a GetXController here, I still would just for the simple sake of using a stateless widget over a stateful widget. If for no other reason than less cluttered UI code and separating business logic.
Also not sure if your Api call function is global or if that's just how you have it in your example, but if it is global I'd create a helper class.
class ApiHelper {
Future<Germany> fetchGermany() async {
final response =
await get(Uri.parse('https://api.corona-zahlen.org/germany'));
if (response.statusCode == 200) {
return Germany.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to get data');
}
}
}
Then your GetX class can look like this.
class DetailController extends GetxController {
Germany germany;
#override
void onInit() async {
super.onInit();
final apiHelper = ApiHelper();
germany = await apiHelper.fetchGermany();
}
}
And here's an example using GetView widget which is just a stateless widget with a built in controller of the type you provided without having to find it.
class GermanyExample extends GetView<DetailController> {
#override
Widget build(BuildContext context) {
// access the initialized Germany object with controller.germany
return // the rest of your UI
}
}
Why not directly use the returned Germany object?
I don't see a need to use GetxController here.
Can be simply used as:
Germany _germany;
#override
void initState() {
super.initState();
fetchGermanyData();
}
fetchGermanyData() async {
final fetchedData = await fetchGermany();
setState(() => _germany = fetchedData);
}
/// use ? : operator to show relevant UI in the build method.

How does WorldEdit handle brushes?

I'm trying to find out how the Bukkit version of WorldEdit handles brushes. I've been looking at the source code on GitHub, but I couldn't find anythig useful. I've tried to recreate the effect, but I can only get it to work when I'm in interaction reach of the target block.
This is about as close as it gets in the source code:
} else if (action == Action.RIGHT_CLICK_AIR) {
if (we.handleRightClick(player)) {
event.setCancelled(true);
}
}
(WorldEdit/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditListener.java, line 143-147)
There are some other parts of code that get very close. I've also looked in /worldedit-core, but nothing there either.
Could someone help me here?
Edit: This is how I try to do it:
public static void onRightClick (PlayerInteractEvent event) {
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
Location location = event.getClickedBlock().getLocation();
if (event.getItem() != null) {
if (event.getItem().getItemMeta().equals(ItemManager.wand.getItemMeta())) {
Player player = event.getPlayer();
player.getWorld().doStuff(location);
}
}
}
}
Edit #2: what I'm most curious about is: How does WE select the location to apply the brush if you are outside of interaction reach?
I needed to use BlockIterators for this. The final code looks like this:
public class BoomWandEvent implements Listener {
#EventHandler
public static void onRightClick (PlayerInteractEvent event) {
Player player = event.getPlayer();
if (event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.RIGHT_CLICK_AIR) {
if (player.getInventory().getItemInMainHand().equals(ItemManager.explosionWand)) {
Location eyePos = player.getEyeLocation();
BlockIterator raytracer = new BlockIterator(eyePos, 0.0D, player.getClientViewDistance() * 16);
while (raytracer.hasNext()) {
Location location = raytracer.next().getLocation();
if (player.getWorld().getBlockAt(location).getType() != Material.AIR && player.getWorld().getBlockAt(location).getType() != Material.CAVE_AIR && player.getWorld().getBlockAt(location).getType() != Material.VOID_AIR) {
player.getWorld().createExplosion(location, 4f);
return;
}
}
}
}
}
}
Thanks to Rogue for helping!

Exposing BLOC streams via fields, methods, or getter

I am using the BLOC pattern for my latest Flutter app and I started out using something like this for my output streams:
class MyBloc {
// Outputs
final Stream<List<Todo>> todos;
factory MyBloc(TodosInteractor interactor) {
final todosController = BehaviorSubject<List<Todo>>()
..addStream(interactor.todos);
return MyBloc._(todosController);
}
MyBloc._(this.todos);
}
but slowly I found myself doing something more like this, using a method (or getter) after awhile:
class MyBloc {
final TodosInteractor _interactor;
// Outputs
Stream<List<Todo>> todos(){
return _interactor.todos;
}
MyBloc(this._interactor) { }
}
For people who want to see... getter for todos in TodosInteractor:
Stream<List<Todo>> get todos {
return repository
.todos()
.map((entities) => entities.map(Todo.fromEntity).toList());
}
When I look at the differing code, I see that the first example uses a field versus a method to expose the stream but I couldn't figure out why I would choose one over the other. It seems to me that creating another controller just to push through the stream is a little much... Is there a benefit to this other than being immutable in my todos stream definition? Or am I just splitting hairs?
Well maybe this will not be a best answer but it is a good practice expose your output stream using get methods. Below a example of a bloc class that i have written to a project using RxDart.
class CityListWidgetBloc {
final _cityInput = PublishSubject<List<Cidade>>();
final _searchInput = new PublishSubject<String>();
final _selectedItemsInput = new PublishSubject<List<Cidade>>();
// exposing stream using get methods
Observable<List<Cidade>> get allCities => _cityInput.stream;
Observable<List<Cidade>> get selectedItems => _selectedItemsInput.stream;
List<Cidade> _searchList = new List();
List<Cidade> _selectedItems = new List();
List<Cidade> _mainDataList;
CityListWidgetBloc() {
//init search stream
_searchInput.stream.listen((searchPattern) {
if (searchPattern.isEmpty) {
_onData(_mainDataList); // resend local data list
} else {
_searchList.clear();
_mainDataList.forEach((city) {
if (city.nome.toLowerCase().contains(searchPattern.toLowerCase())) {
_searchList.add(city);
}
});
_cityInput.sink.add(_searchList);
}
});
}
//getting data from firebase
getCity( {#required String key}) {
FirebaseStateCityHelper.getCitiesFrom(key, _onData);
//_lastKey = key;
}
searchFor(String pattern) {
_searchInput.sink.add(pattern);
}
void _onData(List<Cidade> list) {
_mainDataList = list;
list.sort((a, b) => (a.nome.compareTo(b.nome)));
_cityInput.sink.add(list);
}
bool isSelected(Cidade item) {
return _selectedItems.contains(item);
}
void selectItem(Cidade item) {
_selectedItems.add(item);
_selectedItemsInput.sink.add(_selectedItems);
}
void selectItems(List<Cidade> items){
_selectedItems.addAll( items);
_selectedItemsInput.sink.add( _selectedItems );
}
void removeItem(Cidade item) {
_selectedItems.remove(item);
_selectedItemsInput.sink.add(_selectedItems);
}
dispose() {
_cityInput.close();
_searchInput.close();
_selectedItemsInput.close();
}
}

Moving from hard-coded to SOLID principles in PHP

I am actually reading theory about clean code and SOLID principles. I know understand well that we should program to an interface and not to an implementation.
So, I actually try to apply those principles to a little part of my code. I would like to have your advice or point of view so I can know if I am going in the good direction. I'll show you my previous code and my actual so you can visualize the evolution.
To start, i had a method in my controller to check some requirements for every step of an order process (4 steps that the user have to follow in the right order => 1 then 2 then 3 and then 4)
This is my old code :
private function isAuthorizedStep($stepNumber)
{
$isStepAccessAuthorized = TRUE;
switch($stepNumber) {
case self::ORDER_STEP_TWO: // ORDER_STEP_TWO = 2
if (!($_SESSION['actualOrderStep'] >= ORDER_STEP_ONE)) {
$isStepAccessAuthorized = FALSE;
}
break;
case self::ORDER_STEP_THREE:
if (!($_SESSION['actualOrderStep'] >= ORDER_STEP_TWO)) {
$isStepAccessAuthorized = FALSE;
}
break;
...
}
return $isStepAccessAuthorized;
}
public function orderStepTwo()
{
if ($this->isAuthorizedStep(self::ORDER_STEP_TWO) {
return;
}
... // do some stuff
// after all the verifications:
$_SESSION['actualOrderStep'] = ORDER_STEP_TWO
}
Trying to fit to SOLID principles, I splited my code following this logic:
Extracting hard-coded logic from controllers to put it in classes (reusability)
Using Dependency Injection and abstraction
interface RuleInterface {
public function matches($int);
}
class StepAccessControl
{
protected $rules;
public function __construct(array $rules)
{
foreach($rules as $key => $rule) {
$this->addRule($key, $rule);
}
}
public isAccessGranted($actualOrderStep)
{
$isAccessGranted = TRUE;
foreach($this->rules as $rule) {
if (!$rule->matches($actualOrderStep) {
$isAccessGranted = FALSE;
}
}
return $isAccessGranted;
}
public function addRule($key, RuleInterface $rule)
{
$this->rules[$key] = $rule;
}
}
class OrderStepTwoRule implements RuleInterface
{
public function matches($actualStep)
{
$matches = TRUE;
if (!($actualStep >= 1)) {
$isStepAccessAuthorized = FALSE;
}
return $matches;
}
}
class StepAccessControlFactory
{
public function build($stepNumber)
{
if ($stepNumber == 1) {
...
} elseif ($stepNumber == 2) {
$orderStepTwoRule = new OrderStepTwoRule();
return new StepAcessControl($orderStepTwoRule);
}...
}
}
and then in the controller :
public function stepTwoAction()
{
$stepAccessControlFactory = new StepAccessControlFactory();
$stepTwoAccessControl = $stepAccessControlFactory(2);
if (!$stepTwoAccessControl->isAccesGranted($_SESSION['actualOrderStep'])) {
return FALSE;
}
}
I would like to know if I get the spirit and if I am on the good way :)