A new cool project by Kilim Choi that lets you make a pull request with your engineering blog, that got quite a few stars on Github (4k+ currently).
And, that's how my name got the be next to The Great Ones
Make your pull request too!
A new cool project by Kilim Choi that lets you make a pull request with your engineering blog, that got quite a few stars on Github (4k+ currently).
And, that's how my name got the be next to The Great Ones
Make your pull request too!
From an official blog post, Ionic Analytics Alpha
gives you all the data you need to better understand and optimize your push notifications, deployments, and much, much more.
The go on to say that
You can chart your app’s progress, from the time of its initial release, and see which marketing strategies were most (or least) effective. You can even gain insights into your app’s demographics, allowing you to see how well your app is doing within a given population.
Some of the data this will be able to provide is:
If you were like me - thinking that this will cost some amount, here's what they say:
During the alpha period, Ionic Analytics will be 100% free. In the future, we’ll release tiered pricing based on usage and will continue to offer a free tier.
All this is indeed remarkable, as Ionic team released push support and live updates just few weeks ago. Also, for developers alike, they announced Ionic Market where you'll be able to make plugins for other users (and, I guess sell them too?). So, IMHO Ionic is building an awesome ecosystem and I bet they'll become the best hybrid platform! What is left to see is how will the actual price tiers look like.
This is the simplest example which shows how to POST data from an Ionic app to a PHP server.
The tutorial covering the Ionic version 2 can be found here. The tutorial covering the Ionic version 3 can be found here.
To see it in action:
If you want to make it work from your server:
ionic start ionicServerSendTest blank
// Ionic Starter App // angular.module is a global place for creating, registering and retrieving Angular modules // 'starter' is the name of this angular module example (also set in a <body> attribute in index.html) // the 2nd parameter is an array of 'requires' angular.module('starter', ['ionic']) .run(function($ionicPlatform) { $ionicPlatform.ready(function() { // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard // for form inputs) if (window.cordova && window.cordova.plugins.Keyboard) { cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); } if (window.StatusBar) { StatusBar.styleDefault(); } }); }) .controller('AppCtrl', function($scope, $http) { $scope.data = {}; $scope.submit = function(){ var link = 'http://nikola-breznjak.com/_testings/ionicPHP/api.php'; $http.post(link, {username : $scope.data.username}).then(function (res){ $scope.response = res.data; }); }; });
<?php //http://stackoverflow.com/questions/18382740/cors-not-working-php if (isset($_SERVER['HTTP_ORIGIN'])) { header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}"); header('Access-Control-Allow-Credentials: true'); header('Access-Control-Max-Age: 86400'); // cache for 1 day } // Access-Control headers are received during OPTIONS requests if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}"); exit(0); } //http://stackoverflow.com/questions/15485354/angular-http-post-to-php-and-undefined $postdata = file_get_contents("php://input"); if (isset($postdata)) { $request = json_decode($postdata); $username = $request->username; if ($username != "") { echo "Server returns: " . $username; } else { echo "Empty username parameter!"; } } else { echo "Not called properly with username parameter!"; } ?>
As you can see from the code, the first part is explained in detail in this StackOverflow question, and it basically solves the CORS issue that you would otherwise run into.
The second part, explained in detail in this StackOverflow question, deals with the way you POST data from Ionic (basically an AngularJS app) to your PHP server. The gist is that AngularJS POSTs by default in a JSON format, and thus you have to json_decode the data that comes to your PHP server.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> <title></title> <link href="lib/ionic/css/ionic.css" rel="stylesheet"> <link href="css/style.css" rel="stylesheet"> <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above <link href="css/ionic.app.css" rel="stylesheet"> --> <!-- ionic/angularjs js --> <script src="lib/ionic/js/ionic.bundle.js"></script> <!-- cordova script (this will be a 404 during development) --> <script src="cordova.js"></script> <!-- your app's js --> <script src="js/app.js"></script> </head> <body ng-app="starter" ng-controller="AppCtrl"> <ion-pane> <ion-header-bar class="bar-stable"> <h1 class="title">Ionic Blank Starter</h1> </ion-header-bar> <ion-content padding="true"> <form ng-submit="submit()"> <label class="item item-input item-stacked-label"> <span class="input-label">Username</span> <input type="text" name="username" placeholder="enter username" ng-model="data.username"> </label> <input class="button button-block button-positive" type="submit" name="submit" value="Submit to server"> </form> <div class="card"> <div class="item item-text-wrap"> Response: <b ng-bind="response"></b> </div> </div> </ion-content> </ion-pane> </body> </html>
Here you basically created a form with an username input field and with a submit button. Using AngularJS ng-submit you're saying that once the submit button is clicked AngularJS should handle it within the submit() function which you defined in app.js file before. Input username uses the ng-model to bind to the variable on the $scope so that you can then use it in your submit() function.
Previously I wrote about running Node.js apps with Nodemon and Forever but nowdays I'm using the ever so slightly more professional PM2.
Running your Node.js application by hand is, well, not the way we roll. Imagine restarting the app every time something happens, or god forbid application crashes in the middle of the night and you find about it only in the morning - ah the horror. PM2 solves this by:
To install PM2, run the following command:
sudo npm install pm2 -g
To start your process with PM2, run the following command (once in the root of your application):
pm2 start server.js
As you can see from the output shown on the image below, PM2 automatically assigns an App name (based on the filename, without the .js extension) and a PM2 id. PM2 also maintains other information, such as the PID of the process, its current status, and memory usage.
As I mentioned before, the application running under PM2 will be restarted automatically if the application crashes or is killed, but an additional step needs to be taken to get the application to launch on system startup (boot or reboot). The command to do that is the following:
pm2 startup ubuntu
The output of this command will instruct you to execute an additional command which will enable the actual startup on boot or reboot. In my case the note for the additional command was:
sudo env PATH=$PATH:/usr/local/bin pm2 startup ubuntu -u nikola
If you want to learn more about the additional PM2 options you can take a look at this post.
I'm a big fan of Stack Overflow and I tend to contribute regularly (am currently in the top 0.X%). In this category (stackoverflow) of posts I will will be posting my top rated questions and answers. This, btw, is allowed as explained in the meta thread here.
My question was:
I have this as the style template:
<Style x:Key="myDogToggleButton1" TargetType="ToggleButton" BasedOn="{x:Null}"> <Setter Property="FocusVisualStyle" Value="{x:Null}"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ToggleButton"> <Grid> <Image Name="Normal" Source="/images/dogs/dog1.png"/> <Image Name="Pressed" Source="/images/dogs/dog3.png" Visibility="Hidden"/> <Image Name="Disabled" Source="images/dogs/dog5.png" Visibility="Hidden"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsPressed" Value="True"> <Setter TargetName="Normal" Property="Visibility" Value="Hidden"/> <Setter TargetName="Pressed" Property="Visibility" Value="Visible"/> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter TargetName="Normal" Property="Visibility" Value="Hidden"/> <Setter TargetName="Disabled" Property="Visibility" Value="Visible"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
And now I want another one which is based on the upper one, and this doesn't work:
<Style x:Key="myDogToggleButton2" TargetType="ToggleButton" BasedOn="{DynamicResource myDogToggleButton1}"> <Setter Property="Normal" Value="/images/dogs/dog2.png" /> <Setter Property="Pressed" Value="/images/dogs/dog2.png" /> <Setter Property="Disabled" Value="/images/dogs/dog2.png" /> </Style>
The error message I get is:
The member "Pressed" is not recognized or is not accessible. The member "Normal" is not recognized or is not accessible. The member "Disabled" is not recognized or is not accessible.
I suspect that my different style calling is wrong, so please point out the error.
The answer, by user Heena Patil, was:
Try this
Resource
<Window.Resources> <Style x:Key="myDogToggleButton1" TargetType="ToggleButton"> <Style.Resources> <BitmapImage x:Key="Normal" UriSource="Images/darblue_tab.png"/> <BitmapImage x:Key="Pressed" UriSource="Images/img-whitebg.png" /> <BitmapImage x:Key="Disabled" UriSource="Images/img-greenbg.png"/> </Style.Resources> <Setter Property="FocusVisualStyle" Value="{x:Null}"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ToggleButton"> <Grid> <Image Name="Normal" Source="{DynamicResource ResourceKey=Normal}" Stretch="Fill"/> <Image Name="Pressed" Source="{DynamicResource ResourceKey=Pressed}" Visibility="Hidden"/> <Image Name="Disabled" Source="{DynamicResource ResourceKey=Disabled}" Visibility="Hidden"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsPressed" Value="True"> <Setter TargetName="Normal" Property="Visibility" Value="Hidden"/> <Setter TargetName="Pressed" Property="Visibility" Value="Visible"/> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter TargetName="Normal" Property="Visibility" Value="Hidden"/> <Setter TargetName="Disabled" Property="Visibility" Value="Visible"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="myDogToggleButton2" TargetType="ToggleButton" BasedOn="{StaticResource myDogToggleButton1}"> <Style.Resources> <BitmapImage x:Key="Normal" UriSource="Images/img-darkbg.png" /> <BitmapImage x:Key="Pressed" UriSource="Images/Screenshot_5.png"/> <BitmapImage x:Key="Disabled" UriSource="Images/img-bluebg.png"/> </Style.Resources> </Style> </Window.Resources>Xaml
<Grid> <ToggleButton HorizontalAlignment="Left" Style="{StaticResource myDogToggleButton1}"/> <ToggleButton HorizontalAlignment="Right" Style="{StaticResource myDogToggleButton2}"/> </Grid>Update Using single style.
<Grid> <ToggleButton Height="300" Width="300" HorizontalAlignment="Left" Style="{StaticResource myDogToggleButton1}"/> <ToggleButton Height="300" Width="300" Style="{StaticResource myDogToggleButton1}" HorizontalAlignment="Right"> <ToggleButton.Resources> <BitmapImage x:Key="Normal" UriSource="Images/img-darkbg.png" /> <BitmapImage x:Key="Pressed" UriSource="Images/Screenshot_5.png"/> <BitmapImage x:Key="Disabled" UriSource="Images/img-bluebg.png"/> </ToggleButton.Resources> </ToggleButton> </Grid>
Here are my notes from an awesome 4th Infobip Dev Days 2015 conference:
[toc]
SELECT dep, salary, SUM(salary) OVER (PARTITION BY dep) FROM ...
Everybody knows indexing is important for performance, yet nobody takes the time to learn and apply it properly.
Yesterday (10.06.2015) Ionic announced the Deploy Alpha which enables you to update your app without having to wait for the review & approval.
They say that
Ionic Deploy lets you update your app on demand for any changes that do not require binary modifications.
You can roll back to a previous version of your app, automatically apply updates, and control every aspect of the upgrade.
Also, the features that they list as upcoming are stunning to say the least:
This is pretty awesome to be honest, and really shows that there is future for Ionic framework and that it's a great time to be a hybrid app developer.
You can learn more about it from the official blog post.
[18.09.2015] edit: I honestly can't believe it! This awesome book is now also available as an audiobook! Now I'll be able to listen to this ever so slightly awesome content even in my car! John Sonmez, congratulations!, this is probably the first ever programming related book to be published as an audiobook!
I reviewed the book Soft Skills: The Software Developer's Life Manual by John Sonmez with 5 stars on Amazon with the following comment:
I believe Soft Skills will indeed become every software developers' life manual, in a similar way as Code Complete 2 is.
I really enjoyed the book, and am recommending it to all my "IT" friends (just lent it today to a co-worker :)) - John Sonmez really poured his whole life experience into this, and for this I thank him since I think we all have something to learn from a man who made almost 50 courses for Pluralsight, wrote a bestseller, retired at 33, was a fitness model, bodybuilding contestant, and who is, well, just pure awesome. Btw, I also found that he's damn speedy in answering any emails, so kudos for not being a hot headed superstar author as some these days play out to be.
The book is divided in 7 chapters, and it's packed with awesome content. Those of you who have been following my Books category know that I like to mark the passages that I find valuable from books that I read, like for example:
but here I won't be putting them online since that would be a whole lot portion of the book, and I don't want to be chased for some copyright issues . Instead I'll just show you the images of the chapters and comment a bit about them.
In the first section John talks about topics concerning ones career and steps to take in order to make the most out of it. Topics ranging from how to hack the interview, how to actually set goals, work as a freelancer, and even how to quit your job.
In the second section John talks about how to create your blog as a first thing you should do to start marketing yourself. John also has a free email course on how to build a successful blog, so make sure to get that free resource if you're into starting your own blog, or increasing the views of your existing one.
In the third section John talks about why is continuous learning something you signed up for the minute you decided to make programming your calling. Also, he explains his own 10-step process for learning, which he used to learn and produce almost 50 courses on Pluralsight.
In fourth section John talks about methods and techniques he uses in order to stay crazily productive as he is. Few of them are KanbanFlow and Pomodoro technique.
In the fifth section John shares his own method of how he retired at the age of 33. He seems to be highly influenced by authors such as Robert Kiyosaki, and you can see my notes from his book Rich Dad Poor Dad.
In sixth section John talks about the importance of fitness in developers life as a tool for increased productivity and better well-being. Also, he covers few of the tech gear for geeks like me (I love my FitBit).
Section seven is all about having the right mental attitude, and I'll quote one of my favorite authors, Napoleon Hill: "You can do it if you believe you can". If you're interested, you can read more Napoleon Hill quotes from my notes from his book Think and Grow Rich.
After the book I went on to check out his http://simpleprogrammer.com blog, and what's awesome is that he gives a free email course on how to build a successful blog. Am currently on week 5, and am really learning some key things on what one should do in order to increase his blog credibility and, well, views. So, hope to see those 100k+ users monthly soon 😉
I'm a big fan of Stack Overflow and I tend to contribute regularly (am currently in the top 0.X%). In this category (stackoverflow) of posts I will will be posting my top rated questions and answers. This, btw, is allowed as explained in the meta thread here.
My question was:
How to hide the cursor in Awesomium - I tried this:
<awe:WebControl x:Name="webBrowser" Cursor="None" Source="http://example.com/"/>
but the cursor still shows.
I figured that I could alter the CSS of the page by adding the following line:
*{ cursor: none; }
But, is there a solution for when I don't have the access to the actual page that I'm showing?
The answer, by user Sjoerd2228888, was:
You can use a ResouceInterceptor and manipulate the page on the fly to insert custom CSS.
EDIT:
The following implementation should do the job. (It assumes there is a text.css file)
class ManipulatingResourceInterceptor : IResourceInterceptor { public ResourceResponse OnRequest(ResourceRequest request) { Stream stream = null; //do stream manipulation if (request.Url.ToString() == "http://your.web.url/test.css") { WebRequest myRequest; myRequest = WebRequest.Create(request.Url); Stream webStream = myRequest.GetResponse().GetResponseStream(); StreamReader webStreamReader = new StreamReader(webStream); string webStreamContent = webStreamReader.ReadToEnd(); stream = webStream; string extraContent = "*{cursor: none;}"; webStreamContent += extraContent; byte[] responseBuffer = Encoding.UTF8.GetBytes(webStreamContent); // Initialize unmanaged memory to hold the array. int responseSize = Marshal.SizeOf(responseBuffer[0]) * responseBuffer.Length; IntPtr pointer = Marshal.AllocHGlobal(responseSize); try { // Copy the array to unmanaged memory. Marshal.Copy(responseBuffer, 0, pointer, responseBuffer.Length); return ResourceResponse.Create((uint)responseBuffer.Length, pointer, "text/css"); } finally { // Data is not owned by the ResourceResponse. A copy is made // of the supplied buffer. We can safely free the unmanaged memory. Marshal.FreeHGlobal(pointer); stream.Close(); } } return null; } public bool OnFilterNavigation(NavigationRequest request) { return false; } }
A video worth watching if you're wondering how you should market your App. Also, a cool link I just stumbled upon today is the one on GitHub: App launch guide.
Btw, if you too like to increase your video playback speed, and you miss that in vimeo videos, check this post out to resolve this issue.