<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Nathachai Thongniran on Medium]]></title>
        <description><![CDATA[Stories by Nathachai Thongniran on Medium]]></description>
        <link>https://medium.com/@jojoee?source=rss-128e746b4b88------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*LFCzlTuc1zAN7XH4imJROA.jpeg</url>
            <title>Stories by Nathachai Thongniran on Medium</title>
            <link>https://medium.com/@jojoee?source=rss-128e746b4b88------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 15 Apr 2026 02:53:59 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@jojoee/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Text-to-Image Generation 2023, AI’s Journey and What’s Next]]></title>
            <link>https://medium.com/@jojoee/text-to-image-generation-2023-ais-journey-and-what-s-next-34762e5a06b3?source=rss-128e746b4b88------2</link>
            <guid isPermaLink="false">https://medium.com/p/34762e5a06b3</guid>
            <dc:creator><![CDATA[Nathachai Thongniran]]></dc:creator>
            <pubDate>Sat, 28 Oct 2023 05:00:23 GMT</pubDate>
            <atom:updated>2023-10-28T05:00:23.610Z</atom:updated>
            <content:encoded><![CDATA[<p>In this article, we’ll walk through the story of text-to-image AI technology. We aren’t going to dive deep into hard tech stuff. Instead, we’ll focus on how it helps make new products and changes industries. We’ve splitted the article up into three parts.</p><ul><li>First, an introduction to where this tech came from.</li><li>Second, then we’ll talk about what it can do now.</li><li>Lastly, we’ll dream a little about what it might do in the future.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/775/0*7pL95SAEP96I6FTo.jpg" /><figcaption><a href="https://letstryai.com/midjourney-aesthetics-guide/">wizard making technological discoveries in his laboratory</a></figcaption></figure><h3>Introduction</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*RkywxTfeEIBgNRSU.jpeg" /><figcaption><a href="https://towardsdatascience.com/training-deep-neural-networks-9fdb1964b964">Deep Neural Networks</a></figcaption></figure><p>“Deep Neural Networks” rocketed in the ’20s, thanks to loads of data and super-fast computing. Text-to-image technology, since the mid-2010s, stepped up big time with these networks in 2022. This tech takes text and images, and blends them together making things easier to understand and use.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*cG9Hq6txZa5ZAn1k.jpg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*TNum0MsD7KGcaEML" /><figcaption><a href="https://filmora.wondershare.com/ai/midjourney-prompt.html">Midjouney — text-to-image product</a>, <a href="https://www.brookings.edu/articles/chatgpt-educational-friend-or-foe/">ChatGPT — prompt and provide a detailed response</a></figcaption></figure><p>A big moment arrived on July 12, 2022, when a <a href="https://www.midjourney.com/showcase/recent/">Midjourney</a> text-to-image product hit open beta. It could spawn images from words (text prompts) and it left everyone dumbfounded. Then, on November 30, 2022, <a href="https://chat.openai.com/">ChatGPT</a> launched making a massive impact. It showed us the power of these models and with the understanding of the model, we’re now ready for more.</p><p>As part of “Deep Neural Networks”, different techniques have come and gone over the years.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*nLChJbAhLzigv5Yw.png" /><figcaption><a href="https://sthalles.github.io/intro-to-gans/">Generative Adversarial Networks (GAN)</a></figcaption></figure><p>2014–2016, <a href="https://sthalles.github.io/intro-to-gans/">Generative Adversarial Networks (GANs)</a> helped create images between “real” and “fake”. Developed by Ian Goodfellow in 2014, GAN was just the beginning.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*WKHx1nGmk3b8yilt.jpg" /><figcaption><a href="https://github.com/hanzhanggit/StackGAN">StackGAN</a></figcaption></figure><p>2016–2018, A significant stride was made with StackGAN They made high-quality images from words by using two stages — stage 1) creating a rough image from text, and stage 2) then making it better using the rough image and text.</p><p>2017, <a href="https://arxiv.org/abs/1711.10485">AttnGAN</a> improved upon StackGAN by introducing attention mechanisms</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*4X78xxQUZ-N0BxaD.jpg" /><figcaption><a href="https://www.youtube.com/watch?v=Q9FGUii_4Ok">OpenAI DALL-E 2 — Top 10 Best Images! 🤯</a></figcaption></figure><p>2020+, with a combo of successful models from NLP and GANs for better image output. Prime examples are <a href="https://openai.com/dall-e-2">DALL-E by OpenAI</a> which makes awesome images from words.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/435/0*3zQvLPb4gyAhkmhq.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/250/0*DLFT2rMs4CuSmQNt.jpg" /><figcaption><a href="https://github.com/CompVis/latent-diffusion">Latent Diffusion Models</a>, An image generated by Stable Diffusion based on the text prompt “a photograph of an astronaut riding a horse”</figcaption></figure><p>2022, The current hot shot is <a href="https://en.wikipedia.org/wiki/Stable_Diffusion">Stable Diffusion</a> (based on diffusion techniques introduced in 2015), launched in 2022. It starts with random noise and tries to guess the original image. Interestingly, while training, noise is removed from the image. But in use, we reverse it — input is noise and it tries to guess the original image. It further compresses the image, making it more effective, faster, and smaller.</p><h3>Current</h3><p>These days, everyone is using the “diffusion” technique as a fundamental model. Notably, a significant change came through the way we command the generated image, called “prompt”.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*QAy3KFVuaCt-Bk7K.jpg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/791/1*9Rvy5xtozzI74hvQTEWXGA.png" /><figcaption><a href="https://aituts.com/adding-midjourney-bot-discord-server/">Midjourney Discord Server</a>, <a href="https://docs.midjourney.com/docs/prompts">Midjourney Prompts document</a></figcaption></figure><p>Navigating prompts to get an expected image requires a certain level of skill, and because of that, we now have the role of “prompt engineering.” People with this expertise know how to guide text-to-image AI to churn out desired visual outputs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/720/0*WBLxuS1rAgh2GJzU.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*X-G6cw0cbXHsT6Y2RHPqqQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*c1QULFLTG5Qkpir9c6fVWw.png" /><figcaption><a href="https://medium.com/@techlatest.net/stable-diffusion-and-control-net-a-beginners-guide-9efefe2790f">Control-Net</a> — Let us control diffusion models, <a href="https://promptbase.com/">PromptBase</a> — prompt marketplace, <a href="https://promptperfect.jina.ai/">promptperfect</a> — guide your prompt</figcaption></figure><ul><li>You have no idea what to prompt? There is a prompt marketplace, for buying and selling prompts like <a href="https://promptbase.com/">PromptBase</a></li><li>If guidance is all you need, <a href="https://promptperfect.jina.ai/">PromptPerfect</a> offers help</li><li>Need to control an image’s pose? Try <a href="https://stable-diffusion-art.com/controlnet">controller</a>.</li><li>Dealing with low-resolution images? <a href="www.upscale.media">Upscale Media</a> has got you</li><li>Need a free tool? everyone loves free stuff, and guess what? “Diffusion” can be used for free at <a href="https://huggingface.co/CompVis/stable-diffusion">huggingface.co/CompVis/stable-diffusion</a>.</li><li>Explore more style: although the generic model might need fine-tuning to give your images a unique style, you can also get styled models from <a href="https://civitai.com/models?tag=style">civitai.com</a></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VZ3vpgh7wcs-O7AxccSX7w.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/909/1*lAw67iR3RVvdE_K6T43Nfw.png" /><figcaption><a href="https://www.youtube.com/watch?v=NPJNPrshhTo">Adobe Firefly</a> — text-to-image, inpaint</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/644/1*ZWOlazo-zH7i5NX2iH5pBw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/0*DQVdBn2M--JhcbhF" /><figcaption>recoloring, <a href="https://www.adobe.com/products/illustrator/text-to-vector-graphic.html">text-to-vector-graphic</a></figcaption></figure><p>Now you can tailor to the style you want, only one more step is to add generated image to your daily working tool like “Adobe Illustrator”. Recently, <a href="https://www.adobe.com/sensei/generative-ai/firefly.html">Adobe Firefly</a> — released built-in text-to-image generation, no need external tool any more. Feature like</p><ul><li>text-to-image</li><li>inpaint / fil the space</li><li>recoloring</li><li>text-to-vector-graphic</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/597/0*lUQo-krF2-UkmETP" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/751/0*0mMlnmFdvPyqxs3G.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/879/1*ZGIOn4tJuurnIemv5sdMYw.png" /><figcaption><a href="https://medium.com/merzazine/drawing-hands-and-ai-78b501df0085">Drawing Hands and AI</a>, <a href="https://semicolon.dev/midjourney/how-to-make-consistent-characters">Midjourney — Consistent Characters</a>, <a href="https://civitai.com/models/120096">Pixel Art XL — pixel art model</a></figcaption></figure><p>Despite progressing leaps and bounds, text-to-image AI presents ongoing challenges.</p><ul><li>Weird shapes like hands still a challenge</li><li>Maintaining image consistency across various prompts and there is some workaround for that</li><li>Various file support like SVG, PNG, JPG, and other formats</li><li>Specific styles generated like pixel-art style</li></ul><p>Despite these hurdles, the journey to perfecting text-to-image AI moves on, and the future holds exciting possibilities.</p><h3>Future in the next 3 years</h3><p>Predicting the future can be quite a gamble, but it’s always exciting. With sound intuition and industry knowledge, we might gain a valuable head start. Here’s a glimpse into what we might expect.</p><ul><li>We anticipate high-resolution image generation and detailed control over outputs will become commonplace.</li><li>The boundary between “real” and “generated” will blur to a point where distinguishing one from the other will be impossible.</li><li>Moreover, the role of “prompt engineer” will become a general skill — something every user should master, just like Microsoft Word or Excel.</li><li>Increasingly, we might find ourselves acting more like “auditors” or “tailors” of generated images, using AI tools to pivot, demo, or test ideas rapidly, significantly boosting our productivity.</li><li>Moreover, AI, and specifically text-to-image models, will likely become built-in features of relevant existing products. Take, for instance 1) the vector generation integrated into Adobe Firefly, 2) or the coding assistant GitHub Copilot in Visual Studio Code and IntelliJ IDEA, 3) ChatGPT could expand capabilities to include image generation and understanding, 4) and even Gmail could employ AI for email composition.</li><li>Company can either tap into it by using 1) APIs like <a href="https://openai.com/pricing">OpenAI API</a> or 2) develop and utilize their own models akin to Retro <a href="https://astropulse.gumroad.com/l/RetroDiffusion">Diffusion Extension for Aseprite</a>.</li><li>While this presents an exciting landscape, I believe big companies would hold an advantage due to their substantial resources and existing user base.</li><li>Yet, AI startups can thrive by strategically focusing on niche markets. They need to find areas substantial enough for survival yet too small to grab big company attention.</li><li>In terms of models, while a “one model suits all styles” approach will likely be developed, its huge size and corresponding processing power requirements might keep it from widespread real-world usage. Instead, specialized niche models might be more viable.</li><li>Fully automated, virtual models to promote products could become ingrained in our commerce systems.</li><li>Legal and ethical debates around AI and copyright issues will continue, requiring thoughtful regulation.</li><li>Above all, one thing is clear: AI presents “Significant Business Opportunities”. There are many undiscovered business ideas in AI waiting to be unearthed in the coming years. Let’s wait and see!</li></ul><h3>Conclusion</h3><p>The journey of text-to-image generation has been an eventful one. From humble beginnings to a significant boom with advancements in “deep neural networks”, this technology has gone through a radical transformation.</p><p>The Midjourney shows potential of this technology, leading to an array of exceptional results. This progress isn’t lost on industry players who rapidly adapted it into their products, a prime example being Adobe Firefly.</p><p>Our predictions for the future of the technology, while speculative, are filled with continued growth. The impact of text-to-image technology is far-reaching. It’s opened up numerous opportunities across different industries and, as we move forward, it is likely to become a tool used by everyone.</p><p>As we conclude this journey, one thing we know for certain is this: no matter where we go from here, text-to-image generation will play a substantial part in shaping our digital landscape.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=34762e5a06b3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Agoda GPT Hackathon 2023: My Journey]]></title>
            <link>https://medium.com/@jojoee/agoda-gpt-hackathon-2023-my-journey-be41356e6a6d?source=rss-128e746b4b88------2</link>
            <guid isPermaLink="false">https://medium.com/p/be41356e6a6d</guid>
            <dc:creator><![CDATA[Nathachai Thongniran]]></dc:creator>
            <pubDate>Fri, 31 Mar 2023 06:25:31 GMT</pubDate>
            <atom:updated>2023-04-06T16:35:36.977Z</atom:updated>
            <content:encoded><![CDATA[<p>My name is Joe, and I am a Software Engineer at Agoda. Recently, I participated in the Agoda GPT hackathon, and I am excited to share my journey and the wonderful atmosphere that I experienced during this event. I hope that my story will be a source of inspiration and guidance for all those seeking to participate in a hackathon. In this article, I will walk you through the following points:</p><ol><li>Introduction</li><li>GPT In Agoda</li><li>Preparation for the Hackathon</li><li>Hackathon days</li><li>Evening Presentation</li><li>Useful Resources</li><li>Conclusion</li></ol><p>So, let us dive. For the technical details, you also can find them in the “Useful Resource” section.</p><h3><strong>Introduction</strong></h3><p>ChatGPT is a chatbot that can communicate with humans via text input and has reached an impressive milestone of a million users in under a week. This technology is becoming ubiquitous, but how can we harness its incredible capabilities, and is it worth investing our time in learning it? With technology advancing at such a rapid pace, hackathons offer an excellent opportunity to dive into new technologies.</p><p>Hackathons are exciting events that bring together groups of people to collaborate on a project within a specific timeframe, such as Global Game Jam. Personally, I have taken part in hackathons, such as Global Game Jam, and found them to be both enjoyable and rewarding. Working with friends in a time-constrained environment makes for a fast, fun, and efficient learning experience. If you are keen on exploring cutting-edge technologies like AI, participating in a hackathon could be the ideal starting point.</p><h3>GPT In Agoda</h3><p>At Agoda, we are constantly exploring new technologies, and GPT is one promising technology that we are particularly interested in due to its potential for advancing various applications. We heavily rely on Slack as our primary messaging platform to facilitate seamless communication among our SE (Software Engineer) team. As a result, we have developed an internal Slackbot that is contextually designed around Agoda’s Confluence Space.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/518/1*LPSKNI_6WCVDh9TIWDJg-Q.png" /><figcaption>Agoda GPT-Slack-Bot — Architecture</figcaption></figure><p>The diagram shows how Slackbot was built, which can be simplified into the following steps;</p><ol><li>We collect Confluence data, indexing and saving it.</li><li>When receiving a trigger (we use emoji) then we get the user’s “query” and find a high similarity context (against the indexing data from 1)</li><li>We create a prompt that combines “query” and “context”</li><li>Then we use that generated prompt to call OpenAI API</li><li>After getting the OpenAI API response, we return to the user with a reference Slack thread URLs</li></ol><p>The generated prompt, looking like this.</p><pre>Given these contexts below <br>-------------------------------- <br>&lt;context&gt; <br>-------------------------------- <br>If the given context is relevant to the question,<br>use it to help answer the question <br>Please generate an answer. <br>Answer the question: &lt;query&gt;</pre><p>At first, I was skeptical about the effectiveness of this approach. But much to my surprise, it worked well, providing satisfactory responses with relevant references. Then, in February 2023, Agoda announced an internal hackathon. I spent a week researching GPT and its capabilities and decided to participate.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/584/1*MFhUr6QdbzQlrIx6E0H07g.png" /><figcaption>Agoda GPT-Slack-Bot — Example Response</figcaption></figure><h3>Preparation for the Hackathon</h3><p>To summarize what we did, a week prior to the event, we conducted further research. We brainstormed, proposed, and discussed ideas within the department, which we then categorized into six sections. In total, 197 people joined the event, resulting in 41 teams. Personally, I decided to join a team called<strong> “SupportHero” </strong>with some of my friends.</p><h3>Hackathon days</h3><p>At the beginning of the hackathon, the CTO and other organizers introduced the event and provided guidelines to assist us in developing our projects and preparing for presentations. My team was: Abhishek Kumar Pandey, Carlin Campbell, Nathachai Thongniran, Rajesh Veeranki, Tzahi Hakikat, and Venkat Shukla.</p><h4>First day: Grooming Day</h4><p>After dedicating almost a day to ideation and planning, our team settled on a project called “SupportHero.” Our idea was to leverage Slack data to create a more efficient system for addressing common inquiries. Given that Slack is the primary messaging platform for Agoda’s software engineering team, we felt that it would be the most relevant and up-to-date data source. SupportHero aimed to tackle repetitive questions that often surface. It featured two main functionalities:</p><ol><li>Answer the question (aim to answer repetitive questions)</li><li>Summary the Slack thread then update the Confluence FAQ page</li></ol><h4>Second day: Workday</h4><p>On the second day of the hackathon, it was all about putting in the work to get our project ready for the demo. We had delicious food served. One thing that made this day even more enjoyable was having the assistance of ChatGPT and GitHub Co-pilot in writing our code.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_uPXKqBZRCrpNg54FvMd_Q.jpeg" /><figcaption>Agoda GPT Hackathon — Free Lunch</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/799/1*eybQ92c5ubrLrZgGnanDHg.png" /><figcaption>ChatGPT — Write Me a PII method</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1005/1*u3qZ2sA11HQa7sC94Qwk9w.png" /><figcaption>GitHub Copilot — Suggest Test Case</figcaption></figure><h4>Third day: make it ready</h4><p>On the third day of the hackathon, we dedicated our efforts to enhancing our project’s functionality and appearance. We modified the bot to include reference Slack thread URLs in its responses, which would provide additional support even if the answer were not entirely accurate. Additionally, some team members worked on creating a captivating demo presentation that included recording, image and video editing, and slide creation.</p><p>Initially designed to handle repetitive tickets, our bot eventually evolved into an FAQ page. Realizing its potential, we decided to make it available on channels where repetitive tickets were common. As we continued to develop the bot, we realized that all channels could benefit from its functionality, particularly with the summarize feature. Look at how the bot’s recommendation function works!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/888/1*heCLUarLww35CgsIA1O4Sg.png" /><figcaption>SupportHero — Example Response</figcaption></figure><h3>Evening Presentation</h3><p>During our presentation, I was responsible for ensuring that our bot remained operational for those who wanted to try it out. The energy in the room was electric, and each team brought their unique ideas. After all the teams had presented, it was time for the awards.</p><p>My team won an award for “Best Use of Historical Data.”</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7OpBkA3HqNEQaOrUtGCHPg.jpeg" /><figcaption>Award — Best Use of Historical Data — SupportHero</figcaption></figure><h3>Useful Resources</h3><p>Here are resources that you might want to check out.</p><ul><li><a href="https://github.com/hwchase17/langchain">https://github.com/hwchase17/langchain</a></li><li><a href="https://github.com/jerryjliu/gpt_index">https://github.com/jerryjliu/gpt_index</a></li><li><a href="https://github.com/dair-ai/Prompt-Engineering-Guide">https://github.com/dair-ai/Prompt-Engineering-Guide</a></li><li><a href="https://medium.com/@francois.ascani/running-chatgpt-on-your-internal-confluence-documentation-d7761aa8fc68">https://medium.com/@francois.ascani/running-chatgpt-on-your-internal-confluence-documentation-d7761aa8fc68</a></li><li><a href="https://medium.com/@silvio.pavanetto/confluence-gpt-automating-confluence-page-creation-with-chatgpt-707be9464cb3">https://medium.com/@silvio.pavanetto/confluence-gpt-automating-confluence-page-creation-with-chatgpt-707be9464cb3</a></li><li><a href="https://github.com/openai/openai-cookbook/blob/main/examples/Question_answering_using_embeddings.ipynb">https://github.com/openai/openai-cookbook/blob/main/examples/Question_answering_using_embeddings.ipynb</a></li><li><a href="https://www.mlq.ai/fine-tuning-gpt-3-question-answer-bot/">https://www.mlq.ai/fine-tuning-gpt-3-question-answer-bot/</a></li></ul><h3>Conclusion</h3><p>As the world rapidly advances with technology, we are convinced that it can enhance productivity and positively impact our lives. GPT is one such technology that we find remarkable and believe will have a significant impact on everyone. As a technology company that embraces the intersection of travel and innovation, Agoda provided us with the perfect environment to unleash our creativity and potential. If this resonates with you, we invite you to <a href="https://careersatagoda.com/vacancies/?search=&amp;teams%5B%5D=Technology">join us</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=be41356e6a6d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My MacBook setup for web development 2022]]></title>
            <link>https://medium.com/@jojoee/my-macbook-setup-for-web-development-2022-ae77e6fe8d6a?source=rss-128e746b4b88------2</link>
            <guid isPermaLink="false">https://medium.com/p/ae77e6fe8d6a</guid>
            <category><![CDATA[macbook]]></category>
            <category><![CDATA[vscode-extension]]></category>
            <category><![CDATA[program]]></category>
            <category><![CDATA[macos]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[Nathachai Thongniran]]></dc:creator>
            <pubDate>Sun, 05 Jun 2022 06:00:18 GMT</pubDate>
            <atom:updated>2022-08-14T04:45:28.193Z</atom:updated>
            <content:encoded><![CDATA[<p>My Macbook started to perform slowly. For some random reason, I decided to format my MacBook. Here is a step of mine to set it up, hope this might help you a little bit :)</p><p>First of all, I backup all files to an external hard disk and then follow the step below.</p><h3>Hardware</h3><p>My normal workstation is minimal, just a computer and 1 monitor.</p><p>When I connect my MacBook to the monitor, my external monitor seem to display a bit differently e.g. brightness. So I need to re-adjust it.</p><h3>System Preferences</h3><p>I usually open or take the screenshot of my setting of the old one beside then just copy/follow one by one.</p><ul><li>Dock &amp; Menu Bar</li><li>Mission Controrl</li><li>Spotlight</li><li>Notifications &amp; Focus</li><li>Internet Accounts</li><li>Trackpad</li><li>Sharing</li><li>Keyboard</li><li>Finder<br>- New Finder windows show: Downloads<br>- View &gt; Show View Options &gt; Always open in view list (Use as Defaults)</li></ul><h3>Ordering</h3><p>Order Dock, Sidebar, and organize Launchpad</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/85/1*yQ6DBNEDSYR5ZyvYmAMhuQ.png" /><figcaption>Dock: order</figcaption></figure><h3>SSH</h3><p>Setup a new SSH key for the Git repository which depends on the registry you use. We can use the old existing SSH key, but I do follow the security practice that suggest to generate new one for each machine.</p><ul><li>Bitbucket, <a href="https://support.atlassian.com/bitbucket-cloud/docs/set-up-an-ssh-key/">Set up an SSH key</a></li><li>GitHub, <a href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent">Generating a new SSH key and adding it to the ssh-agent</a></li><li>GitLab, <a href="https://docs.gitlab.com/ee/user/ssh.html">Use SSH keys to communicate with GitLab</a></li></ul><h3>Program</h3><ul><li>Git, <a href="https://github.com/git-guides/install-git">install</a>, and <a href="https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup">setup globally</a></li></ul><pre># setup<br>git config --global user.name &quot;Nathachai Thongniran&quot;<br>git config --global user.email &quot;inid3a@gmail.com&quot;</pre><pre>git config --list<br>git config --global user.name<br>git config --global user.email</pre><ul><li>XCode</li><li><a href="https://code.visualstudio.com/">VSCode</a>, install, setup global <a href="https://code.visualstudio.com/docs/getstarted/settings">settings.json</a> and <a href="https://code.visualstudio.com/docs/getstarted/keybindings">keybindings.json</a></li><li>Drive: <a href="https://www.google.com/drive/">Google Drive</a>, <a href="https://www.microsoft.com/en-ww/microsoft-365/onedrive/online-cloud-storage">One Drive</a>, <a href="https://www.dropbox.com/">Dropbox</a></li><li><a href="https://www.jetbrains.com/toolbox-app/">Jetbrains toolbox</a> and install <a href="https://www.jetbrains.com/datagrip">DataGrip</a>, <a href="https://www.jetbrains.com/pycharm/">PyCharm</a>, and <a href="https://www.jetbrains.com/idea/">IntelliJ IDEA</a></li><li><a href="https://www.sourcetreeapp.com/">Sourcetree</a>, Git client</li><li><a href="https://www.google.com/chrome/">Google Chrome</a>, a web development browser with great debugging tools. install, import bookmark, and setup</li></ul><pre>chrome://settings/syncSetup/advanced<br>chrome://settings/content</pre><ul><li><a href="https://www.videolan.org/">VLC</a>, free and open-source, portable, cross-platform media player software and streaming media server</li><li><a href="https://www.docker.com/">Docker</a>, a tool for container technology</li><li><a href="https://www.postman.com/">Postman</a>, API testing platform</li><li><a href="https://k8slens.dev/">Lens</a>, UI client for Kubernetes</li><li><a href="https://cyberduck.io/">Cyberduck</a>, a cross-platform UI client for file storage servers</li><li>Messaging Channel: <a href="https://slack.com/">Slack</a>, <a href="https://www.microsoft.com/en-ww/microsoft-teams/download-app">Microsoft Teams</a>, <a href="https://discord.com/">Discord</a>, <a href="https://telegram.org/">Telegram</a></li><li><a href="https://theunarchiver.com/">The Unarchiver</a>, compress and uncompress files</li></ul><h3>VSCode Extensions</h3><p>My Best IDE ever. General programming language of mine is JavaScript and Python. So these extensions are generally around it.</p><ul><li><a href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint">ESLint</a>, a lining tool for JavaScript</li><li><a href="https://marketplace.visualstudio.com/items?itemName=Tim-Koehler.helm-intellisense">Helm Intellisense</a>, Syntax Highlighter for <a href="https://helm.sh/">Helm</a></li><li><a href="https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter">Jupyter</a>, it is required to install the Python extension</li><li><a href="https://marketplace.visualstudio.com/items?itemName=zhuangtongfa.Material-theme">One Dark Pro</a>, my only theme</li><li><a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode">Prettier</a>, code formatting for many programming languages</li><li><a href="https://marketplace.visualstudio.com/items?itemName=ms-python.python">Python</a>, a feature-rich extension for Python</li><li><a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh">Remote-SSH</a>, allow using remote machine via SSH</li><li><a href="https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer">Live Server</a>, local server with live reload feature</li><li><a href="https://marketplace.visualstudio.com/items?itemName=chenxsan.vscode-standardjs">StandardJS</a>, another listing tool for JavaScript</li><li><a href="https://marketplace.visualstudio.com/items?itemName=jojoee.conda-cheatsheet">Conda Cheatsheet</a>, open the Conda cheatsheet inside the editor</li></ul><h3>Terminal</h3><p>Terminal setup is simple iterm2 + ohmyzsh and here is the tutorials</p><ul><li><a href="https://www.freecodecamp.org/news/how-to-configure-your-macos-terminal-with-zsh-like-a-pro-c0ab3f3c1156/">How to Configure your macOs Terminal with Zsh like a Pro</a></li><li><a href="https://gist.github.com/kevin-smets/8568070">iTerm2 + Oh My Zsh + Solarized color scheme + Source Code Pro Powerline + Font Awesome + [Powerlevel10k] — (macOS)</a></li><li><a href="https://medium.com/ayuth/iterm2-zsh-oh-my-zsh-the-most-power-full-of-terminal-on-macos-bdb2823fb04c">iTerm2 + zsh + oh-my-zsh The Most Power Full Terminal on macOS</a></li></ul><h3>Command-line interface (CLI) Program</h3><p>Here is a list of CLI tools</p><ul><li><a href="https://brew.sh/">Homebrew</a>, and also install</li></ul><pre>brew help<br>brew update<br>brew upgrade</pre><pre># wget, tool for retrieving files over HTTP<br># nmap, network scanner<br># telnet, provide a bidirectional interactive text communication<br># k6, load testing<br># wrk, load testing (another one)<br># jq, command-line JSON processor<br># kubectl, CLI to interact with Kubernetes clusters<br>brew install wget nmap telnet k6 wrk jq kubectl</pre><ul><li>Cloud Provider CLI: <a href="https://cloud.google.com/sdk/docs/install">Install the gcloud CLI</a>, <a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html">Installing or updating the latest version of the AWS CLI</a></li><li><a href="https://github.com/nvm-sh/nvm">Node Version Manager (NVM)</a>, install and set the default NodeJS version</li></ul><pre>nvm ls<br>nvm ls-remote<br>nvm install 16.15.0<br>nvm alias default 16.15.0<br>nvm use default 16.15.0</pre><ul><li>Conda, Python package management. I do prefer <a href="https://docs.conda.io/en/latest/miniconda.html">Miniconda</a></li></ul><pre>conda -V<br>conda search python<br>conda create — name base3.10.4 python=3.10.4<br>conda activate base3.10.4</pre><ul><li><a href="https://github.com/commitizen/cz-cli">Commitizen</a>, defines a standard way for Git commit message</li></ul><pre>npm install -g commitizen<br>npm install -g cz-conventional-changelog<br>echo &#39;{ &quot;path&quot;: &quot;cz-conventional-changelog&quot; }&#39; &gt; ~/.czrc</pre><ul><li><a href="https://github.com/jojoee/chromepass">chromepass</a>, password generation which runs 100% locally</li></ul><pre>npm install -g chromepass<br>chromepass</pre><ul><li><a href="https://github.com/httpie/httpie">httpie</a>, command-line HTTP client</li></ul><pre>python -m pip install --upgrade httpie</pre><ul><li>Datastores<br>- <a href="https://gist.github.com/ibraheem4/ce5ccd3e4d7a65589ce84f2a3b7c23a3">Installing Postgres via Brew</a><br>- <a href="https://gist.github.com/nrollr/3f57fc15ded7dddddcc4e82fe137b58e">Install MySQL on macOS Sierra</a><br>- <a href="https://redis.io/docs/getting-started/installation/install-redis-on-mac-os/">Install Redis on macOS</a></li></ul><p>Thank you so much for your time, see ya!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ae77e6fe8d6a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Visual Studio Code extension: แชร์ประสบการณ์ในการพัฒนา]]></title>
            <link>https://medium.com/@jojoee/visual-studio-code-extension-%E0%B9%81%E0%B8%8A%E0%B8%A3%E0%B9%8C%E0%B8%9B%E0%B8%A3%E0%B8%B0%E0%B8%AA%E0%B8%9A%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B8%93%E0%B9%8C%E0%B9%83%E0%B8%99%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B8%9E%E0%B8%B1%E0%B8%92%E0%B8%99%E0%B8%B2-8e3cc7db893a?source=rss-128e746b4b88------2</link>
            <guid isPermaLink="false">https://medium.com/p/8e3cc7db893a</guid>
            <category><![CDATA[vscode-extension]]></category>
            <category><![CDATA[experience]]></category>
            <category><![CDATA[vscode]]></category>
            <dc:creator><![CDATA[Nathachai Thongniran]]></dc:creator>
            <pubDate>Sun, 15 Mar 2020 12:41:05 GMT</pubDate>
            <atom:updated>2020-03-17T09:51:12.535Z</atom:updated>
            <content:encoded><![CDATA[<p>สวัสดีครับ 2 อาทิตย์ที่ผ่านมา ผมได้ทำ open source ตัวนึง ซึ่งคิดว่า ขั้นตอน, แนวคิด และตัวงาน อาจจะมีประโยชน์ไม่มากก็น้อยแก่ผู้อ่าน เลยอยากจะมาแชร์ให้ฟังครับ โดยจะเรียงลำดับ ตามนี้ครับ</p><p>Code สำหรับ project นี้นะครับ: <a href="https://github.com/jojoee/vscode-conda-cheatsheet">https://github.com/jojoee/vscode-conda-cheatsheet</a></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/78285de5354ba1f13bb7ca6be6ad6046/href">https://medium.com/media/78285de5354ba1f13bb7ca6be6ad6046/href</a></iframe><h3>1. แรงบัลดาลใจ</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/969/1*0PIbQkmyVHapDJzS6IAdGw.png" /><figcaption><a href="https://marketplace.visualstudio.com/">Visual Studio Code Marketplace</a></figcaption></figure><p>ปัจจุบัน editor ที่ผมใช้อยู่เป็นหลักเลยคือ <a href="https://code.visualstudio.com/">Visual Studio Code</a> (มีใช้ตัวอื่นบ้างก็จะเป็นเครือของ <a href="https://www.jetbrains.com/">Jetbrains</a>)</p><p>ด้วยความที่เป็น Editor ที่เร็ว, มี extension ให้เลือกใช้เยอะและใช้งานได้ดี เลยสนใจและอยากลองทำ extension ขึ้นมาบ้าง</p><p>ซึ่งในเนื้อหาถัดๆไปจะขอใช้ตัวอักษร VSCode แทนคำว่า Visual Studio Code นะครับเพื่อความสะดวกในการอ้างถึง</p><p>.</p><h3>2. กำหนดขอบเขตของงาน</h3><p>ส่วนนี้จะเป็นการกำหนดที่สิ่งคาดหวังและเวลาที่จะใช้ในการพัฒนา</p><ol><li>อยากจะศึกษา ว่าเราจะสามารถทำ VSCode extension ได้อย่างไร</li><li>จากข้อ 1) เราก็จะเข้าใจคนออกแบบโปรแกรมมากขึ้น ว่าถ้าเราอยากจะออกแบบโปรแกรมให้มีส่วนต่อขยาย (extension) จะออกแบบอย่างไร หรืออย่างน้อยก็ต้องคำถึงเรื่องอะไรบ้าง</li><li>ต้องการใช้เวลาประมาณ 1 อาทิตย์ในการพัฒนา (พอเอาเข้าจริงๆใช้เวลาประมาณ 2 อาทิตย์)</li><li>จากข้อ 3) ต้องหา project ที่น่าจะมีประโยชน์และสามารถใช้งานได้จริงภายใน 1 อาทิตย์</li></ol><h3>3. รายละเอียด project</h3><p>จากที่ค้นคว้ามาก็เจอ project “cheatsheet” เนี่ยแหละที่คิดว่าจะสามารถทำให้เสร็จทันได้ภายใน 1 อาทิตย์</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/921/1*4iZTscXGilcHT074BfGkpg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WiuJBO80fhpwPOkYNJyK0A.png" /><figcaption>ซ้าย kubectl: <a href="https://github.com/dennyzhang/cheatsheet-kubernetes-A4">https://github.com/dennyzhang/cheatsheet-kubernetes-A4</a>, ขวา VSCode: <a href="https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf">https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf</a></figcaption></figure><p>cheatsheet เหมือนเป็นพวกสรุปสูตร ตาม domain ต่างๆเช่น VSCode cheatsheet, Docker cheatsheet, Next.js cheatsheet ซึ่งมีได้หลายรูปแบบเช่น website หรือ pdf file ตามตัวอย่างด้านบนครับ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*x4C7MjotidRLcSVam6G-SQ.png" /><figcaption>Search result <a href="https://marketplace.visualstudio.com/search?term=cheatsheet&amp;target=VSCode&amp;category=All%20categories&amp;sortBy=Relevance">Cheatsheet</a> in VSCode marketplace</figcaption></figure><p>ซึ่งใน VSCode marketplace ก็ยังมี extension จำพวกนี้ค่อนข้างน้อยอยู่ดังรูป มีแค่ประมาณ 8 extensions เอง</p><p>โดยสรุปแล้ว project ที่จะทำก็จะเป็น Conda cheatsheet โดยมีทั้งหมด 3 features ดังตัวอย่างด้านล่างได้แก่</p><p>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/946/1*ndWEXKm9MfEGUbEFs97NQg.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/958/1*AOJJ3Gnb_HOWDnLNpLPMew.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/956/1*nneNE9ndD9II671be5cFtg.png" /><figcaption>1. pdf version, 2. website version, 3. webview version</figcaption></figure><ol><li>เปิด Conda cheatsheet เวอร์ชั่น pdf ไฟล์ (เหมือนเปิด pdf file ให้)</li><li>เปิด Conda cheatsheet เวอร์ชั่น website (เปิด website ด้วย url ตรงๆ)</li><li>เปิด Conda cheatsheet เวอร์ชั่น webview (เราเขียนเนื้อหาด้วย html ขึ้นมาเอง)</li></ol><p>(<a href="https://docs.conda.io/en/latest/">Conda</a> เป็น ตัวจัดการ Python environment management, “คล้ายๆ” <a href="https://github.com/nvm-sh/nvm">nvm</a> ที่เป็น Node Version Manager ของ Javascript)</p><h3>4. ประสบการณ์ระหว่างการพัฒนา</h3><p>เนื้อหาในส่วนนี้จะเป็นเนื้อหาในระหว่างการพัฒนาตัว extension</p><h4>4.1 เวลาในการพัฒนา</h4><p>ใช้เวลาในการพัฒนาไปทั้งหมด 2 อาทิตย์ (จากที่วางแผนไว้แค่ 1 อาทิตย์)</p><ul><li>1 อาทิตย์แรกใช้เวลาไปกับการอ่าน tutorial แล้วเอา code ของเขามาลองเล่น</li><li>1 อาทิตย์ถัดมา ใช้ไปกับการพัฒนาจริงๆ</li></ul><p>ตัวอย่าง website สอนการเขียนและตัวอย่าง code</p><ul><li><a href="https://code.visualstudio.com/api/get-started/your-first-extension">Your First Extension</a></li><li><a href="https://code.visualstudio.com/api/get-started/extension-anatomy">Extension Anatomy</a></li><li><a href="https://code.visualstudio.com/api/extension-guides/webview">Webview API</a></li><li><a href="https://www.digitalocean.com/community/tutorials/how-to-create-your-first-visual-studio-code-extension">How To Create Your First Visual Studio Code Extension</a></li><li><a href="https://www.youtube.com/watch?v=OhfOcqSU62g">Creating Your First Visual Studio Code Extension</a></li><li><a href="https://www.youtube.com/watch?v=4tk0Ak-dEjs">How to Create a VSCode Extension</a></li><li><a href="https://github.com/microsoft/vscode-extension-samples">https://github.com/microsoft/vscode-extension-samples</a></li></ul><h4>4.2 การพัฒนา</h4><p>การพัฒนาของ project นี้จะขึ้น project ตั้งต้นด้วยเครื่องมือจากคำแนะนำ VSCode website (จากบทความ <a href="https://code.visualstudio.com/api/get-started/your-first-extension">Your First Extension</a>) เองเลย ซึ่งเราจะใช้ <a href="https://yeoman.io/">Yeoman</a></p><p>เราจะต้องลง Yeoman และ <a href="https://yeoman.io/generators/">generator</a> ซึ่งมันจะ setup ส่วนประกอบต่างๆให้เรา เช่น ทำให้ build tool, unit test, lint tool, etc.</p><p>(yo / Yeo / Yeoman เป็นเครื่องมือในการทำ โปรเจคตั้งต้น / boilerplate / starter)</p><pre>// example command<br>npm install -g yo generator-code &amp;&amp; yo code</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4xsNhH36kZjK6dZwIqshLQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/525/1*4ApZYUAxDFD_BvwbwllTyw.png" /><figcaption><a href="https://yeoman.io/">Yeoman</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/555/1*_PmFDjN-Fi1-G3zfM4vbFQ.png" /><figcaption>Project structure after run “yo code” with “New Extension (TypeScript)”</figcaption></figure><p>โดยเมื่อ VSCode generator ทำงานเสร็จเราก็จะได้ structure ตามนี้ ซึ่งไม่เหมือนกันตามรูปแบบของ extension (ในที่นี้ผมเลือก “New Extension (TypeScript)”)</p><p>ซึ่งไฟล์หลักๆในการพัฒนาก็จะเป็นไฟล์ “extension.ts” ครับ</p><h4>4.3 indentation ไม่เหมือนกัน</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/461/1*PUsNbUGGBUU9OzAQxYSpKw.png" /><figcaption>คำสั่ง “lint:fix”</figcaption></figure><p>ปัญหาแรกที่เจอมาคือ indentation ไม่ตรงกับที่ผมใช้</p><p>ผมก็เลยเปลี่ยน indentation ทั้งหมดให้เป็น space 2 อัน ด้วย eslint ที่ติดมากับ generator ด้วย คำสั่ง “lint:fix” ใน <a href="https://github.com/jojoee/vscode-conda-cheatsheet/blob/master/package.json#L48">package.json</a></p><p>.</p><p>.</p><p>.</p><h4>4.4 พัฒนา features</h4><p>ในที่นี้เรากะว่าจะพัฒนากันอยู่ 3 features</p><ul><li>Conda Cheatsheet: PDF</li><li>Conda Cheatsheet: Website</li><li>Conda Cheatsheet: Webview</li></ul><p>ถึงแม้จะฟังดูไม่เหมือนกัน แต่เทคนิคที่ใช้นั้นผมตัดสินใจเลือกใช้เทคนิคเดียวกันทั้งหมดคือ webview ครับ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/649/1*qTqUWIDDedz2jkETakO53A.png" /><figcaption><a href="https://github.com/jojoee/vscode-conda-cheatsheet/blob/master/src/extension.ts">https://github.com/jojoee/vscode-conda-cheatsheet/blob/master/src/extension.ts</a></figcaption></figure><ul><li>Conda Cheatsheet: PDF — ใช้ webview embed &lt;img&gt; เข้าไป โดย html</li><li>Conda Cheatsheet: Website — ใช้ webview embed &lt;iframe&gt;</li><li>Conda Cheatsheet: Webview — ใช้ webview เหมือนกัน + ทำ html ขึ้นมาเอง</li></ul><p>สรุปก็คือทั้ง 3 features เราจะใช้เทคนิคเดียวกันหมดคือทำ webview ขึ้นมาครับ</p><h4>4.5 พัฒนา features “Conda Cheatsheet: Webview”</h4><p>โดย feature “Conda Cheatsheet: PDF” และ “Conda Cheatsheet: Website” นั้นค่อนข้างตรงไปตรงมา แต่ feature “Conda Cheatsheet: Webview” เราจำเป็นต้อง เขียน html ขึ้นมาเองใหม่ครับ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/516/1*Iy1qgP1Xxv-P3cE4viyHdw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bRjAc1dHOGlXQCELx4d-1g.png" /><figcaption>Code และ description ซึ่งเป็นสองส่วนหลักๆในการทำ cheatsheet</figcaption></figure><p>ซึ่งปกติแล้ว cheatsheet ทั้งหลายจะประกอบด้วย 2 ส่วนหลักๆครับ ซึ่งก็คือ code และ description แสดงผลซ้ำไปซ้ำมา ทำให้เราตัดสินใจใช้ <a href="https://github.com/pugjs/pug">Pug</a> (เป็น template engine) มา render <a href="https://github.com/jojoee/vscode-conda-cheatsheet/blob/master/tool/template.pug">template</a> ให้เราครับ</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/731/1*FJpmGhbvwIgNV6R53KjdJg.png" /><figcaption><a href="https://github.com/pugjs/pug">https://github.com/pugjs/pug</a></figcaption></figure><h4>4.6 ทำ webview ให้ support light และ dark theme ของ VSCode</h4><p>ใน VSCode นั้นปกติจะมี theme อยู่ 2 แบบ light และ dark ซึ่งเราก็ต้องการที่จะทำให้ support ทั้ง 2 themes โดยการเพิ่มตัวแปรใน css file</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*cPhf-myKZakTiwS9.png" /><figcaption>ทำให้ support ทั้ง 2 themes — ซ้าย: dark theme, ขวา: lighttheme</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/898/1*4erck8rS2OudgHYpfkVESA.png" /><figcaption><a href="https://github.com/jojoee/vscode-conda-cheatsheet/blob/master/asset/custom.css">https://github.com/jojoee/vscode-conda-cheatsheet/blob/master/asset/custom.css</a></figcaption></figure><p>โดยเราจะใช้ตัวแปร “vscode-menu-selectionBackground” และ “vscode-menu-selectionForeground” เพื่อให้ css เราปรับไปตาม VSCode theme ที่เราเลือก (อ้างอิง <a href="https://code.visualstudio.com/api/references/theme-color">Theme Color</a>)</p><h4>4.7 click ที่ code เพื่อที่จะ copy code</h4><p>ใน feature webview นั้นเราต้องการที่จะทำให้สามารถ copy code หลังจาก click ที่ code นั้นๆได้ด้วย เพื่อนำไปวาง (หรือ paste หรือ ctrl + v) เพื่อใช้งานได้ทันที</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/599/1*CwsxJsRQ29VVLKlsJckM6A.png" /><figcaption>Conda Cheatsheet: Webview — screenshot</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/898/1*coW0fDzlnUO4E6R6D3VcJw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/952/1*M6nWa4te-HofiPWtBAoujg.png" /><figcaption><a href="https://github.com/jojoee/vscode-conda-cheatsheet/blob/master/asset/main.js">main.js</a> เป็นตัวส่ง event และ <a href="https://github.com/jojoee/vscode-conda-cheatsheet/blob/master/src/extension.ts">extension.ts</a> เป็นตัวรับ event</figcaption></figure><p>การทำ feature นี้ต้อง setup ตัวส่ง event (ในไฟล์ html ที่ render) และทำตัวรับ event ดังรูปด้านบนครับ</p><h4>4.8 compile template on the fly และ pre-compile</h4><p>ตอนแรกที่ผมพัฒนา “Conda Cheatsheet: Webview” feature ผมตั้งใจให้ เรียก module “pug” ขณะ run-time เพื่อ render “pug” template เป็น html format</p><p>ทำให้เวลาผมทำเป็น VSCode extension package (ขึ้น <a href="https://marketplace.visualstudio.com/vscode">VSCode marketplace</a>) นั้น package ของผมนั้นใหญ่มาก เพราะต้องเอา code ของ “pug” module ขึ้นไปด้วย</p><p>ผมเลยต้องเปลี่ยนเป็น จาก “เปลี่ยน .pug เป็น .html ขณะใช้งาน” เป็น “pre-compile เป็น html ก่อนทำเป็น VSCode extension package”</p><p>ด้านล่างเป็นการเปรียบเทียบลำดับการทำงานของ “ก่อน” และ “หลัง” ปรับแต่ง</p><pre>ก่อน (เปลี่ยน .pug เป็น .html ขณะใช้งาน)<br>- ทำเป็น VSCode extension package เพื่อขึ้น VSCode marketplace<br>- user เรียกใช้งานคำสั่ง<br>- VSCode extension เรียกใช้งาน module “pug” เพื่อแปลง .pug เป็น .html<br>- นำ html ไปใช้งานใน webview</pre><pre>หลัง (pre-compile เป็น html ก่อนทำเป็น VSCode extension package)<br><strong>- </strong>เขียน <a href="https://github.com/jojoee/vscode-conda-cheatsheet/blob/master/tool/compileWebview.js">script</a> ขึ้นมาทำการ แปลง .pug เป็น .html เตรียมไว้เลย<br>- ทำเป็น VSCode extension package เพื่อขึ้น VSCode marketplace<br>- user เรียกใช้งานคำสั่ง<br>- VSCode extension จะเรียกใช้งาน .html (ที่ compile ไว้แล้ว) ไปใช้งานได้เลย</pre><p>ผลก็คือขนาดของ VSCode extension package ลดลงจาก 3.37MB เป็น 359.68KB (ลดไปประมาณ 98%)</p><pre>conda-cheatsheet-1.2.2.vsix (3513 files, 3.37MB) - before<br>conda-cheatsheet-1.2.3.vsix (14 files, 359.68KB) - after</pre><h4>4.9 การทำ gif, screenshot</h4><p>เพื่อเป็นการสาธิตวิธีการใช้งาน ให้ผู้ใช้เข้าใจได้ง่ายขึ้น ว่า VSCode extension นี้ทำอะไรได้บ้าง, โดยที่ผมใช้หลักๆคือ OSX capture screenshot, <a href="https://giphy.com/apps/giphycapture">GIPHY Capture</a> <a href="https://github.com/keycastr/keycastr">KeyCastr</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/0*befRy_d8ZVsHI_08.gif" /><figcaption>Demo of <a href="https://marketplace.visualstudio.com/items?itemName=jojoee.conda-cheatsheet">Conda Cheatsheet</a> VSCode extension</figcaption></figure><h4>4.10 ทำ CI + auto publish ขึ้น VSCode marketplace</h4><p>ขั้นตอนในการ <a href="https://code.visualstudio.com/api/working-with-extensions/publishing-extension">Publishing Extensions</a> คร่าวๆคือ</p><ul><li>สมัคร <a href="https://docs.microsoft.com/azure/devops/organizations/accounts/create-organization-msa-or-work-student">Azure DevOps organization</a></li><li>สร้าง Personal Access Token (PAT) เพื่อใช้ในการ publish VSCode extension</li><li>ใช้ PAT ในการ publish VSCode extension</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/938/1*cbrMcEEWchXgfiwnbX9q6w.png" /><figcaption>Travis CI build of <a href="https://travis-ci.org/github/jojoee/vscode-conda-cheatsheet">jojoee/vscode-conda-cheatsheet</a></figcaption></figure><p>เนื่องจากผมคุ้นเคยกับ <a href="https://travis-ci.org/">Travis CI</a> อยู่แล้ว ก็เลยใช้ตัวนี้ในการทำ CI + auto publish ขึ้น VSCode marketplace ซะเลย</p><p>เพื่อนๆ สามารถดูตัวอย่าง Travis CI config ได้ที่ <a href="https://github.com/jojoee/vscode-conda-cheatsheet/blob/master/.travis.yml">.travis.yml</a> ครับ</p><p>.</p><p>.</p><p>.</p><p>.</p><p>.</p><h3>5. สิ่งที่ควรปรับปรุงแก้ไขและศึกษาทำเพิ่ม</h3><p>สำหรับ project นี้สิ่งที่ยังขาดและสามารถเพิ่มเติมได้ก็คือ การ auomate ครับ เช่น</p><ul><li>feature “Conda Cheatsheet: PDF” — ด้วยความที่เราต้อง download และเปลี่ยนเป็นรูปภาพ ทำให้เรายังต้องทำแบบ manual, ถ้าให้ดีก็น่าจะเขียน script มาทำงานแทนเรา (download + แปลง pdf เป็น image ไฟล์)</li><li>feature “Conda Cheatsheet: Webview” — <a href="https://github.com/jojoee/vscode-conda-cheatsheet/blob/master/tool/compileWebview.js">script</a> สำหรับการ pre-compile จาก .pug เป็น .html นั้นดีแล้ว — แต่ในระหว่างการพัฒนาถ้ามีการเปลี่ยนแปลง .pug, เราไม่ได้เขียน watch task ให้มัน auto compile เมื่อ .pug เมื่อมีการแก้ไข</li><li>ยังไม่ได้เขียน test ใดๆ</li></ul><h3>6. ส่งท้าย</h3><p>ขอบคุณผู้อ่านที่เสียสละเข้ามาเยี่ยมชมนะครับ ผิดพลาดอย่างไร หรือเพิ่มเติมส่วนไหน คอมเม้นด้านล่างได้เลยนะครับ หวังว่าจะเป็นประโยชน์แก่ผู้อ่านไม่มากก็น้อยนะครับ — ลิ้งไปตัว project ครับ <a href="https://github.com/jojoee/vscode-conda-cheatsheet">https://github.com/jojoee/vscode-conda-cheatsheet</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/811/1*mTXoJh7YqWn7LX-AfPicCw.png" /><figcaption><a href="https://marketplace.visualstudio.com/items?itemName=jojoee.conda-cheatsheet">Conda Cheatsheet</a> — extension preview inside VSCode editor</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8e3cc7db893a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[PWA Online hackathon: ประสบการณ์ การเข้าร่วม และ การพัฒนา]]></title>
            <link>https://medium.com/@jojoee/pwa-online-hackathon-%E0%B8%9B%E0%B8%A3%E0%B8%B0%E0%B8%AA%E0%B8%9A%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B8%93%E0%B9%8C-%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B9%80%E0%B8%82%E0%B9%89%E0%B8%B2%E0%B8%A3%E0%B9%88%E0%B8%A7%E0%B8%A1-%E0%B9%81%E0%B8%A5%E0%B8%B0-%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B8%9E%E0%B8%B1%E0%B8%92%E0%B8%99%E0%B8%B2-281e454fdff6?source=rss-128e746b4b88------2</link>
            <guid isPermaLink="false">https://medium.com/p/281e454fdff6</guid>
            <category><![CDATA[tools]]></category>
            <category><![CDATA[games]]></category>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[pwa]]></category>
            <category><![CDATA[hackathons]]></category>
            <dc:creator><![CDATA[Nathachai Thongniran]]></dc:creator>
            <pubDate>Mon, 26 Jun 2017 08:58:48 GMT</pubDate>
            <atom:updated>2017-06-28T04:02:43.965Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*yUrx4P9Y1_KXM_ZZlE4EBA.png" /></figure><p>สวัสดีครับ อาทิตย์ที่ผ่านมา ได้เข้าร่วมงาน <a href="https://pwa.online.hackathon.in.th/">PWA Online hackathon</a> จึงอยากมาแชร์ประสบการณ์ การแข่งขันให้ฟังกันครับ</p><p>โดยมีหัวข้อดังนี้</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/804339b2b49d064bbbcd6fedf82a0a1d/href">https://medium.com/media/804339b2b49d064bbbcd6fedf82a0a1d/href</a></iframe><h3>1. PWA Online hackathon: overview</h3><p>เป็นการแข่ง hackathon แบบ online (ทำที่ไหนก็ได้) ระหว่าง 23–25 มิถุนายน 2560, โดยจะมีกฏหลักๆดังนี้</p><ul><li>ไม่มี backend</li><li>สามารถรันบน static server ได้</li><li>code อยู่บน GitHub</li><li>host อยู่บน Firebase hosting</li><li>application มี Web app manifest</li><li>ติดตั้ง <a href="https://developer.mozilla.org/en/docs/Web/API/Service_Worker_API">Service Worker</a> เพื่อทำให้ใช้งาน ขณะที่ไม่สามารถเชื่อมต่อ internet ได้</li><li>ถ้าจะใช้ Firebase ใช้ได้แค่บางอย่างเท่านั้น — <a href="https://pwa.online.hackathon.in.th/rules">Firebase rules</a></li></ul><p>โดยการให้คะแนนก็จะพิจารณาถึง</p><ul><li>ความสมบูรณ์ของ Web Application</li><li>ความคิดสร้างสรรค์</li><li>การเลือกใช้เทคโนโลยี</li><li>(คะแนนพิเศษ) คะแนน <a href="https://github.com/GoogleChrome/lighthouse">Lighthouse</a> เกิน 98 แต้ม</li><li>(คะแนนพิเศษ) มี Web notification</li><li>(คะแนนพิเศษ)ใช้ Geolocation API หรือ getUserMedia API</li><li>(คะแนนพิเศษ) ทำ Web application เป็น Web VR</li></ul><h3>2. การเตรียมตัว</h3><p>งานนี้ประกาศตั้งแต่ 25 พฤษภาคม เห็นประกาศก็สนใจทันที, ส่วนตัวเป็น web programmer อยู่แล้ว และได้ศึกษา PWA จาก <a href="https://www.udacity.com/course/front-end-web-developer-nanodegree--nd001">Udacity: Front-End Web Developer Nanodegree</a> และ Firebase มาแล้ว</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/743/1*dz1RvxblVqe2kA9k9gVPKQ.png" /><figcaption>Front-End Web Developer Nanodegree</figcaption></figure><p>เลยคิดว่าคงจะต้องศึกษาเพิ่มไม่มากเท่าไร กะไว้ว่าจะใช้ 1 อาทิตย์ก่อนแข่งเตรียมตัว แต่พอเอาเข้าจริง มีเนื้อหาให้ต้องศึกษา ค่อนข้างเยอะเลยทีเดียว ทำให้เตรียมตัวไม่ได้ดีเท่าที่ควร</p><h3>3. Tool ที่ใช้</h3><ul><li>Editor: <a href="https://code.visualstudio.com/">Visual Studio Code</a></li><li>Package manager, dependency management: <a href="https://www.npmjs.com/">npm</a> และ <a href="https://yarnpkg.com/en/">yarn</a></li><li>Development flow, build tool: <a href="http://gulpjs.com/">Gulp</a> และ <a href="https://www.npmjs.com/">npm</a></li><li>Browser: <a href="https://www.google.com/chrome/index.html">Chrome</a> และ <a href="https://www.google.com/chrome/browser/canary.html">Chrome Canary</a></li></ul><h3>4. Package และ Service ที่ใช้</h3><h4>4.1 Unit test</h4><ul><li>Library: <a href="https://mochajs.org/">mocha</a></li><li>Assertion: <a href="http://chaijs.com/">chai</a> ช่วยสนับสนุนการ test แบบ BDD ​(syntax จะเหมือนภาษาพูด)</li><li>Coverage: <a href="https://github.com/istanbuljs/nyc">nyc</a> ช่วยบอกว่า test ที่เราเขียนไป ครอบคลุมกี่ %</li><li>Report: <a href="https://codecov.io/">codecov</a> ใช้งานได้ฟรีสำหรับ coverage report — ตัวอย่าง <a href="https://codecov.io/github/jojoee/pwa-online-hackathon">coverage report ของโปรเจค pwa-online-hackathon</a> บน codecov</li></ul><h4><strong>4.2 Lint tool</strong></h4><p>Lint tool พวกนี้จะช่วยควบคุมคุณภาพของ code ได้เบื้องต้น และช่วยกัน bug ได้บางส่วน</p><ul><li>Javascript: <a href="http://eslint.org/">ESLint</a> และ <a href="https://standardjs.com/">standard</a></li><li>HTML: <a href="https://github.com/yaniswang/HTMLHint">HTMLHint</a></li><li>CSS: <a href="https://github.com/stylelint/stylelint">stylelint</a></li></ul><h4>4.3 Development flow, build flow</h4><ul><li>Static server: <a href="https://github.com/firebase/firebase-tools">firebase/firebase-tools</a> — จริงๆแล้วมีหลายตัว เช่น <a href="http://npmjs.com/package/http-server">http-server</a>, <a href="https://docs.python.org/2/library/simplehttpserver.html">SimpleHTTPServer</a> แต่ตัดสินใจใช้ firebase-tools เพราะยังไงก็ต้องใช้ในการ deploy ขึ้น Firebase hosting ด้วย</li><li>Development flow:ใช้ <a href="https://www.npmjs.com/package/npm-run-all">npm-run-all</a> package รัน ESLint และ Gulp (ทำ concat และ minify ทั้ง javascript และ css ไฟล์) ให้ทำงานไปพร้อมๆกัน</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2fd33f732c0925c5d85493e3d78a24ba/href">https://medium.com/media/2fd33f732c0925c5d85493e3d78a24ba/href</a></iframe><h4>4.4 Source control และ commit conventions</h4><ul><li>Source control: <a href="https://git-scm.com/">Git</a> และเก็บไว้ที่ <a href="https://github.com/">Github</a></li><li>Commit conventions: <a href="https://github.com/commitizen/cz-cli">cz-cli</a> และ <a href="https://github.com/commitizen/cz-conventional-changelog">cz-conventional-changelog</a></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/641/1*mG3Ml47UCnHIe7cEutgvWw.png" /><figcaption>cz-cli and cz-conventional-changelog via “yarn commit” command</figcaption></figure><p>ปกติแล้วเวลาเรา commit เราจะเขียน commit message อะไรก็ได้ — ปัญหาก็คือบางที commit message นั้นสื่อสารไม่ชัดเจนว่า commit นั้นเปลี่ยนแปลงอะไรบ้าง</p><p>โดย tool นี้จะช่วยเลือกหมวดหมู่ของ commit เราให้ ทำให้เราพอจะรู้คร่าวๆ ว่าใน commit นั้นๆทำอะไรบ้าง โดยไม่ต้องดู code ที่เปลี่ยนไปเลย</p><p>แล้วเราจะใช้ <a href="https://www.npmjs.com/package/ghooks">ghooks</a> ช่วยในการ commit ด้วย — โดยเมื่อเรารัน yarn commit เราจะสั่งให้ไปรัน yarn validate ก่อนเสมอ ทำให้ code ถูก validate ก่อนที่จะ commit ทุกครั้ง</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1bf640ee76a91a0b3a977ceea196de61/href">https://medium.com/media/1bf640ee76a91a0b3a977ceea196de61/href</a></iframe><h4>4.5 Build CI service</h4><p>ใช้ <a href="https://travis-ci.org/">Travis CI</a> ในการทดสอบการ build project บน environment ที่ต่างกัน โดย project นี้จะทดสอบบน Node.js version 6, 7 , 8 และตั้งค่าไว้ว่า เมื่อ build สำเร็จก็ให้ทำการสร้าง coverage report ไปที่ <a href="https://codecov.io/github/jojoee/pwa-online-hackathon">โปรเจค pwa-online-hackathon ที่อยู่บน codecov.io</a></p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2dd54ed50761e8836b54eceaa29919b4/href">https://medium.com/media/2dd54ed50761e8836b54eceaa29919b4/href</a></iframe><h4>4.6 Project management tool</h4><p>จะเขียน todo list (รายการที่จะต้องทำ) ลงใน <a href="https://github.com/jojoee/pwa-online-hackathon/blob/master/README.md">README.md</a> ง่ายๆแบบนี้เลย</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/411/1*ecmtp_Lp53Pc2koisuUpzg.png" /><figcaption>README.md — todo list</figcaption></figure><h3>5. ประสบการณ์ระหว่างการแข่งขัน</h3><p>โดยจะไล่ตาม commit timeline</p><h4>23/06@20.00</h4><ul><li>ติดตั้ง tool เช่น Gulp, <a href="https://github.com/firebase/firebase-tools">firebase/firebase-tools</a>, ESLint, etc.</li><li>หา idea — สรุปว่า จะทำเกมแนว clicker / idle games</li></ul><p>โดยจะเป็นเกมอ้างอิงถึงระบบขนส่ง (Public transportation) กะว่าจะใส่อะไรสนุกๆ อย่าง รถม้าลําปาง, Uber, จรวด SpaceX, หรืออะไรแปลกๆลงไป แล้วจะได้ใช้ Geo location API เพื่อที่จะได้คะแนนพิเศษด้วย</p><p>ตัวอย่างเกมแนว clicker / idle games</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/979/1*wHlRw3CdKauYl2ZS37DI1w.png" /><figcaption>Clicker Heroes — <a href="http://store.steampowered.com/app/363970/Clicker_Heroes/">http://store.steampowered.com/app/363970/Clicker_Heroes/</a></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/959/1*1gse7IvxTrI5waouNpF-fQ.png" /><figcaption>AdVenture Capitalist — <a href="http://store.steampowered.com/app/346900/AdVenture_Capitalist/">http://store.steampowered.com/app/346900/AdVenture_Capitalist/</a></figcaption></figure><h4>24/06@01.00</h4><ul><li>นอน</li></ul><h4>24/06@9.30</h4><ul><li>ตั้งค่า tool, lib เช่น ESLint, Firebase, <a href="https://lodash.com/">Lodash</a></li></ul><p>เนื่องจากยังคิด game layout ใน screen size ขนาดต่างๆ ไม่ได้ (เช่น PC, tablet, mobile) เลยทำได้แค่ ตั้งค่า tool, lib ไปเรื่อยๆ</p><h4>24/06@11.00</h4><ul><li>ใส่หิมะ, ดาว, ดาวตก ไปใน background ของ game</li><li>ตั้งค่า Gulp task เช่น concat javascript ทุกไฟล์</li><li>ติดตั้ง <a href="https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/">Web App Manifest</a></li><li>ติดตั้ง <a href="https://github.com/GoogleChrome/lighthouse">GoogleChrome/lighthouse</a> — ไว้ตรวจสอบคุณภาพของ game ตามแนวทางของ PWA (Progressive Web Apps) และ optimze เพื่อเพิ่มคะแนน</li><li>ใส่ <a href="https://developer.mozilla.org/en/docs/Web/API/Service_Worker_API">Service woker</a> (ทำให้ใช้งานขณะที่ไม่สามารถเชื่อมต่อ internet ได้)</li><li>Deploy ไปที่ <a href="https://firebase.google.com/docs/hosting">Firebase hosting</a></li></ul><h4>24/06@18.00</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/408/1*evka-GHUjW4xwsyxy2efmA.gif" /><figcaption>MeteorKiller — game play</figcaption></figure><ul><li>ตัดสินใจเปลี่ยนเกม เนื่องจากคิด game layout บนขนาดต่างๆไม่ออก — เป็นเกมปัจจุบัน <a href="https://github.com/jojoee/pwa-online-hackathon">MeteorKiller: Kill all Star lord’s meteor</a> , โดยใช้ดาวตกที่ได้ทำไว้ก่อนหน้าเป็นตัวหลักของเกม</li><li>ออกแบบและคิด feature ของเกมเพิ่มเติม</li><li>Game over screen</li></ul><h4>24/06@22.00</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/256/1*BmtatyDYNsBMeDB4fs6icw.png" /><figcaption>MeteorKiller — homescreen256.png</figcaption></figure><ul><li>ทำ icon homescreen ของ game กะไว้ว่าจะให้เหมือนดาวตก แบบ modern หน่อยๆ แต่ว่าผลงานที่ได้ ออกมาแล้วดูจะไม่เหมือนไม่สักเท่าไร แต่ก็โอเค</li><li>ใส่ effect ตอน click (กลมๆ เหลืองๆ)</li><li>เพิ่มระบบ score และ high score</li></ul><h4>25/06@01.00</h4><ul><li>นอน</li></ul><h4>25/06@07.00</h4><ul><li>sign-in และ sign-out ด้วย Firebase ผ่าน <a href="https://www.google.com/gmail">Gmail</a></li></ul><h4>25/06@11.00</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/425/1*xoJrs_t3Z0CU473AdwnTzQ.png" /><figcaption>Notification while offline</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/408/1*DHWwcFM-BpV7dLNHUk1tVQ.gif" /><figcaption>Notification while online</figcaption></figure><ul><li>ติดตั้ง <a href="https://firebase.google.com/docs/cloud-messaging/">Firebase notification</a></li><li>ติดตั้ง <a href="https://firebase.google.com/docs/database/">Firebase Realtime Database</a> ไว้เก็บ score และ high score</li><li>ทำ screenshake เมื่อเลือด (life) ในเกมลด — feature นี้จะเป็นการ สั่นจอแบบหลอกๆ (สังเกต ตอนสั่น, จะสั่นแค่ตรง คะแนน ไม่ได้สั่นทั้งจอ เพราะคิดว่า ถ้าสั่นทั้งจอ คนเล่นจะเล่นยาก)</li><li>ใส่เสียง effect เวลาเลือดลด — เอามาจาก <a href="http://www.bfxr.net/">Bfxr</a></li></ul><h4>25/06@16.00 ถึงจบงาน 20.00</h4><p>ทำการเพิ่ม performance และคะแนน <a href="https://github.com/GoogleChrome/lighthouse">GoogleChrome/lighthouse</a></p><ul><li>เพิ่ม start screen เวลาเริ่มเกม, เพื่อให้ไม่ให้เกม render เยอะขณะทำการเปิดเกมขึ้นมา ซึ่งทำให้ใช้ทรัพยากรเครื่องลดลง (ปล. code ส่วนนี้ไม่ค่อยดี เนื่องจากตอนแรกที่ทำ game engine ไม่ได้ออกแบบให้รองรับอะไรแบบนี้ไว้)</li><li>สร้าง debounce function ขึ้นมาใช้เอง แล้วเอา <a href="https://lodash.com/">Lodash</a> ออก</li><li>สร้าง random number และ boolean ขึ้นมาใช้เองแล้วเอา <a href="http://chancejs.com/">Chance.js</a> ออก</li><li>หลังจาก concat + minify ไฟล์ css และ javascript ทั้งหมด — ก็จะใช้ <a href="https://www.npmjs.com/package/gulp-inline-source">gulp-inline-source</a> ในการยัด css และ javascript เข้า index.html ไฟล์เดียวเลย เพื่อจะได้โหลดแค่ไฟล์เดียว และรวมถึงลดปัญหาจาก network latency ด้วย (ปัจจุบันสามารถเอา css เข้าไปได้แล้ว แต่ javascript ยังต้องทำเองอยู่ ด้วยการ copy and paste)</li></ul><h3>6. ปัญหาที่เจอ</h3><h4>6.1 Commit ด้วยคำสั่ง yarn commit</h4><p>ผ่าน commitizen (cz-conventional-changelog) และ ghooks ใช้เวลานานมากประมาณ 60 วินาที ต่อการ commit 1 ครั้ง บน Windows OS</p><h4>6.2 Performance score of Lighthouse</h4><p>คะแนน Performance ของ Lighthouse แกว่งบน Windows OS</p><ul><li>บน Windows คะแนนแกว่งระหว่าง 85–99</li><li>บน OSX จะได้ 99 ตลอด</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mgiOL7a98sT3ZiNrnitmxw.png" /><figcaption>MeteorKiller — Lighthouse score</figcaption></figure><h4>6.3 Lighthouse tool</h4><p>ขณะที่เขียนบทความอยู่ เราสามารถรัน <a href="https://github.com/GoogleChrome/lighthouse">GoogleChrome/lighthouse</a> ได้ 3 แบบ</p><ol><li><a href="https://github.com/GoogleChrome/lighthouse#using-the-node-cli">CLI</a></li><li><a href="https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk?hl=en">Lighthouse Chrome extension</a> ของ <a href="https://www.google.com/chrome/index.html">Chrome Web Browser</a></li><li>Audits tab ใน <a href="https://github.com/GoogleChrome/lighthouse#using-lighthouse-in-chrome-devtools">Chrome DevTools</a> ของ <a href="https://www.google.com/chrome/browser/canary.html">Chrome Canary</a></li></ol><p>ตอนที่พัฒนาบน Windows OS จะใช้วิธีที่ 1 และ 2 พอทดสอบไปสักพัก ก็ใช้งานไม่ได้อีกเลย, จึงใช้วิธีที่ 3 มาโดยตลอด</p><h3>7. สิ่งที่ควรปรับปรุงแก้ไขและศึกษาทำเพิ่ม</h3><h4>7.1 Test และ QA tool เยอะเกินไป</h4><p>บางตัวแทบจะไม่ได้ใช้ เช่น unit test หรือบางตัวก็ไม่แน่ใจว่าคุ้มไหม กับเวลาที่ใช้ไป ในการติดตั้ง, ตั้งค่าและปรับปรุง</p><h4>7.2. Development flow + build flow ในหัวข้อที่ 4.3</h4><ul><li>คิดว่าในส่วนนี้ควรใช้ tool เดียวไปเลย เช่น G<a href="http://gulpjs.com/">ulp</a>, <a href="https://webpack.github.io/">webpack module bundler</a></li><li>คำสั่ง yarn dev ที่ใช้ในการพัฒนาหลัก ยังขาดการเรียกใช้งานบาง tool อยู่เช่น htmlhint และ stylelint</li></ul><h4>7.3 Test</h4><ul><li>Unit test แทบจะไม่ได้ใช้ในโปรเจคนี้เลย</li><li>การทดสอบการแสดงผล — code ส่วนใหญ่เป็นการ render บน canvas จนตอนนี้ก็ยังไม่แน่ใจว่าจะทดสอบ code ส่วนนี้ให้มีให้มีประสิทธิภาพได้อย่างไร (ตอนนี้คิดได้แค่ว่า ถ้าจะทดสอบคงใช้ใช้เทคนิคแบบเดียวกับ <a href="https://github.com/storybooks/storybook">storybooks/storybook</a> ที่ใช้ทดสอบ <a href="https://facebook.github.io/react/">React</a>)</li><li>คำสั่งทดสอบที่เขียนไว้ใน <a href="https://github.com/jojoee/pwa-online-hackathon/blob/master/.travis.yml">.travis.yml</a> ที่ใช้ยังไม่ตอบโจทย์เท่าไร คำสั่ง coverage และ coverage.check ไม่ค่อยได้ใช้เพราะไม่ได้เขียน test สักเท่าไร, ส่วน build นั้นยังไงก็ผ่านเพราะแค่ concat และ minify ไฟล์เฉยๆ</li></ul><pre># .travis.yml<br>script:<br>- npm run build<br>- npm run coverage<br>- npm run coverage.check</pre><h4>7.4 Automated script</h4><p>resize homescreen icon อัตโนมัติ เช่น เวลาทำรูปใหม่ก็จะได้ไม่ต้องมา resize ขนาดเป็นขนาดต่างๆเอง</p><h4>7.5 Code pattern</h4><p>ควรต้องนั่งดูทั้งโปรเจคใหม่อีกที ในโปรเจคผสมหลาย pattern มากเพื่อให้มันทำงานได้ (กลัวเสร็จไม่ทัน) ซึ่งส่วนตัวแล้วคิดว่าเขียนเป็น pattern เดียวกันหมดเลยน่าจะดีกว่า เช่นใช้ ES6 ทั้งโปรเจค</p><h4>8. FAQ</h4><h4>8.1 ทำไมต้องเขียน game engine ขึ้นมาเอง</h4><ol><li>อยากศึกษาการเขียน game engine</li><li>ไม่เข้าใจ core ของ game framework เพียงพอ — ส่วนตัวเคยได้ลองเขียนเกมบนเวบ โดยใช้ <a href="https://phaser.io/">Phaser — game framework</a> มาบ้าง แต่มีปัญหาตรงที่เวลาอยากทำอะไรแปลกๆ ต้องค้น Google ตลอดแทบจะ 100% เพราะเนื่องจากไม่เข้าใจ core ของมัน</li></ol><h4>8.2 ทำไมเอา <a href="https://lodash.com/">Lodash</a> และ <a href="http://chancejs.com/">Chance.js</a> ออก</h4><ol><li>เพื่อศึกษา</li><li>เพื่อรีดประสิทธิภาพให้ได้มากที่สุด</li></ol><p>ผมใช้ debounce ของ <a href="https://lodash.com/">Lodash</a> กับ random number และ boolean ของ <a href="http://chancejs.com/">Chance.js</a> สรุปแค่ 3 functions แต่ขนาดของทั้ง 2 libraries นั้นเยอะมาก ก็เลยตัดสินใจเอาออก แต่อย่างการเล่นไฟล์เสียง นั้นผมไม่ค่อยแน่ใจ ผมก็เลยยังคงใช้ <a href="https://github.com/goldfire/howler.js">howler.js</a></p><h3>9. ส่งท้าย</h3><p>ขอบคุณผู้อ่านที่เสียสละเข้ามาเยี่ยมชมนะครับ — ผิดพลาดอย่างไร, อยากให้ขยายความจุดไหนเพิ่มหรือคิดเห็นอย่างไร คอมเม้นด้านล่างได้เลยครับ</p><p>ท้ายนี้อยากจะขอบคุณคณะผู้จัดงาน และ ผู้สนันสนุนงานด้วยครับที่ได้จัดงานดีๆ แบบนี้ขึ้นมา</p><p>ปล. code อาจไม่ตรงไปบ้าง เพราะตอนนี้ยัง push code ใหม่ขึ้นไปที่ GitHub ไม่ได้ครับ</p><ul><li><a href="https://pwa.online.hackathon.in.th/">PWA Online Hackathon | We challenge you to make awesome PWA</a></li><li><a href="https://github.com/jojoee/pwa-online-hackathon">jojoee/pwa-online-hackathon</a></li></ul><p><em>Updated 1@27/06/2017 เปลี่ยนคำพูดที่ใช้เล็กน้อย<br>Updated 2@28/06/2017 อัพเดทหัวข้อ 7.3 และ เปลี่ยนคำพูดที่ใช้เล็กน้อย</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=281e454fdff6" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ทดสอบเรื่องจ้า]]></title>
            <link>https://medium.com/@jojoee/%E0%B8%97%E0%B8%94%E0%B8%AA%E0%B8%AD%E0%B8%9A%E0%B9%80%E0%B8%A3%E0%B8%B7%E0%B9%88%E0%B8%AD%E0%B8%87%E0%B8%88%E0%B9%89%E0%B8%B2-49cece0bf608?source=rss-128e746b4b88------2</link>
            <guid isPermaLink="false">https://medium.com/p/49cece0bf608</guid>
            <dc:creator><![CDATA[Nathachai Thongniran]]></dc:creator>
            <pubDate>Wed, 10 Feb 2016 02:04:27 GMT</pubDate>
            <atom:updated>2016-02-10T02:04:27.003Z</atom:updated>
            <content:encoded><![CDATA[<p>โหลๆ เทสๆ</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=49cece0bf608" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>