Merge branch 'master' into dev-scripts-and-doc-tweaks

This commit is contained in:
Vamshi Surabhi 2019-08-07 12:08:46 +05:30 committed by GitHub
commit a5a07634a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
381 changed files with 23000 additions and 1487 deletions

View File

@ -21,7 +21,7 @@ import (
"github.com/briandowns/spinner"
"github.com/gofrs/uuid"
"github.com/hasura/graphql-engine/cli/version"
colorable "github.com/mattn/go-colorable"
"github.com/mattn/go-colorable"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
@ -171,6 +171,9 @@ type ExecutionContext struct {
// LogLevel indicates the logrus default logging level
LogLevel string
// NoColor indicates if the outputs shouldn't be colorized
NoColor bool
// Telemetry collects the telemetry data throughout the execution
Telemetry *telemetry.Data
@ -343,6 +346,7 @@ func (ec *ExecutionContext) Spin(message string) {
func (ec *ExecutionContext) setupLogger() {
if ec.Logger == nil {
logger := logrus.New()
logger.Formatter = &logrus.TextFormatter{
ForceColors: true,
DisableTimestamp: true,
@ -351,6 +355,13 @@ func (ec *ExecutionContext) setupLogger() {
ec.Logger = logger
}
if ec.NoColor {
ec.Logger.Formatter = &logrus.TextFormatter{
DisableColors: true,
DisableTimestamp: true,
}
}
if ec.LogLevel != "" {
level, err := logrus.ParseLevel(ec.LogLevel)
if err != nil {

View File

@ -70,6 +70,7 @@ func init() {
f.StringVar(&ec.LogLevel, "log-level", "INFO", "log level (DEBUG, INFO, WARN, ERROR, FATAL)")
f.StringVar(&ec.ExecutionDirectory, "project", "", "directory where commands are executed (default: current dir)")
f.BoolVar(&ec.SkipUpdateCheck, "skip-update-check", false, "Skip automatic update check on command execution")
f.BoolVar(&ec.NoColor, "no-color", false, "do not colorize output (default: false)")
}
// Execute executes the command and returns the error

View File

@ -12,6 +12,8 @@ Examples in this repository support the following cloud function platforms:
* Zeit Now
* Netlify Functions
Note: *If you want to add support for other platforms, please submit a PR or create an issue and tag it with `help-wanted`*

View File

@ -33,7 +33,7 @@ $ cd graphql-engine/community/boilerplates/remote-schemas/google-cloud-functions
Start a local development server (you may need to install dependencies from npm):
```bash
$ npm i --no-save apollo-server express
$ npm i --no-save apollo-server
$ node localDev.js
Output:

View File

@ -1,11 +1,8 @@
const { ApolloServer } = require('apollo-server');
const express = require('express');
const app = express();
const { typeDefs, resolvers } = require('./index');
const helloSchema = new ApolloServer({ typeDefs, resolvers });
const server = new ApolloServer({ typeDefs, resolvers });
helloSchema.listen().then(({ url }) => {
server.listen().then(({ url }) => {
console.log(`schema ready at ${url}`);
});

View File

@ -15,8 +15,8 @@ const frontendTutorial = [
},
{
name: 'Angular',
url: 'https://learn.hasura.io/graphql/angular',
comingSoon: true,
url: 'https://learn.hasura.io/graphql/angular-apollo',
comingSoon: false,
bgClassName: 'angularBg',
disableBgClassName: 'angularDisableBg',
},
@ -75,8 +75,8 @@ const mobileTutorial = [
},
{
name: 'Flutter',
url: 'https://learn.hasura.io/graphql/flutter',
comingSoon: true,
url: 'https://learn.hasura.io/graphql/flutter-graphql',
comingSoon: false,
bgClassName: 'flutterBg',
disableBgClassName: 'flutterDisableBg',
},

View File

@ -0,0 +1,35 @@
import React from 'react';
import '../styles/styles.scss';
class Featured extends React.Component {
render() {
return (
<div className={'whiteBgColor commonSectionWrapper'}>
<div className={'container noPadd'}>
<div className={'featuredWrapper'}>
<div className={'sectionHeader'}>
Weve been featured!
</div>
<div className={'purpleLineSeperator'}>
</div>
<div className={'featuredIconWrapper'}>
<div className={'featuredIcon'}>
<a href="https://frontendweekly.co/issues/152" target="_blank" rel="noopener noreferrer"><img src={'https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/frontend-weekly.png'} alt={'Frontend Weekly'}/></a>
</div>
<div className={'featuredIcon'}>
<a href="https://javascriptkicks.com/articles/202558/jsk-weekly-july-10-2019" target="_blank" rel="noopener noreferrer"><img src={'https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/jsk.png'} alt={'JSK'}/></a>
</div>
<div className={'featuredIcon'}>
<a href="https://react.statuscode.com/issues/138" target="_blank" rel="noopener noreferrer"><img src={'https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/react.png'} alt={'React Statuscode'}/></a>
</div>
<div className={'featuredIcon'}>
<a href="https://news.vuejs.org/issues/142" target="_blank" rel="noopener noreferrer"><img src={'https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/vue-news.png'} alt={'Vue News'}/></a>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default Featured;

View File

@ -1,322 +0,0 @@
/* Testimonial section start here */
.Testimonials {
background-color: #f7f7f7;
}
.TestimonialsSection {
padding: 75px 0;
}
.pageSubHeader
{
font-weight: 600;
font-size: 26px;
text-align: center;
color: #102261;
padding-bottom: 20px;
line-height: normal;
}
.TestimonialsWrapper
{
clear: both;
.pageSubHeader
{
text-align: center;
color: #2b0785;
padding-bottom: 40px;
}
.testimonialsCarouselWrapper
{
// padding-top: 20px;
.testimonialsCarousel
{
.quoteImg
{
position: absolute;
top: -66px;
}
.quoteLeft
{
left: -30px;
}
.quoteright
{
right: -30px;
}
.carouselIndicators
{
bottom: -65px;
li
{
margin: 0 16px;
border: 1px solid #2b0785;
width: 8px;
height: 8px;
}
}
.carouselInner
{
width: 90%;
margin: 0 auto;
min-height: 188px;
.carouselInnerItems
{
margin-bottom: 5px;
padding: 0 20px;
width: 100%;
float: left;
// min-height: 618px;
.indivRectBox
{
background-color: #fff;
border-radius: 2px;
box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.16);
padding: 15px;
position: relative;
// margin-top: 30px;
min-height: 180px;
.pageDescription
{
font-weight: 600;
padding-bottom: 10px;
line-height: 1.5;
width: 97%;
font-size: 14px;
a
{
color: #1f88e5;
}
a:hover
{
text-decoration: none;
color: #1f88e5 !important;
border-bottom: 1px solid #1f88e5 !important;
}
}
.pageDescriptionSmall
{
padding-bottom: 0px;
line-height: normal;
font-weight: 300;
color: #505050;
text-align: left;
a
{
color: #1f88e5;
text-decoration: none;
}
a:hover
{
text-decoration: none;
border-bottom: 1px solid #1f88e5;
}
}
.pageDescription, .pageDescription1
{
text-align: left;
color: #fff;
}
.quotes
{
position: absolute;
top: 20px;
right: 20px;
img
{
width: 23px;
}
.imgSmall
{
width: 20px;
}
}
}
}
}
.carouselControl
{
width: 50px;
display: flex;
align-items: center;
justify-content: center;
background-image: inherit !important;
img
{
height: 25px;
display: inline-block;
}
}
.prodImgSmall
{
max-height: 62px;
}
}
.graphql_discription
{
padding-top: 20px;
color: #fff;
text-align: center;
}
}
}
/* Testimonial section ends here */
@media (max-width: 767px)
{
/* Testimonial section start here */
.TestimonialsWrapper
{
// padding-top: 30px;
.pageSubHeader
{
padding: 0 15px;
padding-bottom: 0;
}
.testimonialsCarouselWrapper
{
padding-top: 0;
.testimonialsCarousel
{
.quoteImg
{
width: 30px;
top: 5px;
}
.quoteLeft
{
left: -15px;
}
.quoteright
{
right: -15px;
}
.carouselInner
{
width: 100%;
padding-bottom: 3px;
.carouselInnerItems
{
padding: 0 0px;
.indivRectBox
{
min-height: auto;
margin-top: 30px;
.pageDescription
{
font-size: 14px;
width: 93%;
}
.pageDescriptionSmall
{
word-break: break-word;
font-size: 15px;
}
.pageDescription1
{
font-size: 13px;
}
.quotes
{
img
{
width: 15px;
}
.imgSmall
{
width: 15px;
}
}
}
}
}
}
}
}
/* Testimonial section ends here */
}
@media (min-width: 768px) and (max-width: 991px)
{
/* Testimonial section start here */
.TestimonialsWrapper
{
.testimonialsCarouselWrapper
{
.testimonialsCarousel
{
.quoteImg
{
width: 60px;
top: -49px;
}
.quoteLeft
{
left: -20px;
}
.quoteright
{
right: -20px;
}
.carouselInner
{
width: 90%;
min-height: 230px;
.carouselInnerItems
{
padding: 0 0px;
// min-height: 768px;
.indivRectBox
{
min-height: 222px;
.pageDescription
{
font-size: 15px;
}
.pageDescriptionSmall
{
word-break: break-word;
font-size: 15px;
}
.quotes
{
img
{
width: 18px;
}
.imgSmall
{
width: 18px;
}
}
.pageDescription1
{
line-height: 1.4;
}
}
}
}
}
}
}
/* Testimonial section ends here */
}
@media(width: 1024px)
{
.TestimonialsWrapper
{
.testimonialsCarouselWrapper
{
.testimonialsCarousel
{
.carouselInner
{
width: 90%;
.carouselInnerItems
{
padding: 0 0px;
.indivRectBox
{
min-height: 213px;
}
}
}
}
}
}
}

View File

@ -1,241 +1,72 @@
import React from 'react';
import '../styles/styles.scss';
class Testimonials extends React.Component {
constructor() {
super();
this.state = {
testimonial: [
{
description: (<span>This is one of the best tutorials I have seen for getting started with GraphQL and React. This is an incredible roadmap for learning these concepts in a linear and digestible way.</span>),
img: 'https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/Eve-Porcello.png',
name: 'Eve Porcello',
twitterLink: 'https://twitter.com/eveporcello',
designation: (<span>Instructor <b>@egghead.io</b></span>),
},
{
description: (<span>This is a really great tutorial for people keen to learn more about GraphQL <span role="img" aria-labelledby="emoji">🚀</span> I just went through the React one, but they have tutorials for Vue, iOS and RN too <span role="img" aria-labelledby="emoji">💙</span> <a href="https://twitter.com/hashtag/2Hours2GraphQL?src=hash" target="_blank" rel="noopener noreferrer">#2Hours2GraphQL</a>.</span>),
img: 'https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/Sibylle.png',
name: 'Sibylle',
twitterLink: 'https://twitter.com/s_ibylle/status/1138143802831585280',
designation: (<span>Typeface <b>@brandung</b></span>),
},
{
description: (<span>Check out this GraphQL <a href="https://twitter.com/hashtag/ReasonML?src=hash" target="_blank" rel="noopener noreferrer">#ReasonML</a> course for Reason React developers by <a href="https://twitter.com/HasuraHQ" target="_blank" rel="noopener noreferrer">@HasuraHQ</a> <a href="https://learn.hasura.io/graphql/reason-react-apollo" target="_blank" rel="noopener noreferrer">https://learn.hasura.io/graphql/reason-react-apollo</a>... “Will this course teach ReasonReact concepts as well?” Hell yes. There are some programming patterns on display in this app that are different from what you see in generally.</span>),
img: 'https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/Imani.png',
name: 'Imanis Father',
twitterLink: 'https://twitter.com/_idkjs/status/1151765251991453696',
designation: (<span>Freelance software developer</span>),
},
]
}
}
render() {
const styles = require('./Styles.module.scss');
const twitter = require('./images/twitter.svg');
const LeftArrow = require('./images/Left-Arrow.png');
const RightArrow = require('./images/Right-Arrow.png');
const quoteLeft = require('./images/quote-left.svg');
const quoteRight = require('./images/quote-right.svg');
const listWrapper = this.state.testimonial.map((list, index) => {
return (
<div key={index} className={'testimonialList'}>
<div className={'quotes'}>
<img src={'https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/quote.svg'} alt={'Quote'} />
</div>
<div className={'testimonialContent'}>
{list.description}
</div>
<div className={'authorWrapper'}>
<div className={'authorImg'}>
<img src={list.img} alt={list.name} />
</div>
<div className={'author'}>
<div className={'name'}>
<a href={list.twitterLink} target={'_blank'} rel="noopener noreferrer">{list.name}</a>
</div>
<div className={'designation'}>
{list.designation}
</div>
</div>
</div>
</div>
);
});
return (
/* Use global styles normally */
<div className={styles.Testimonials}>
<div className="container">
<div className={styles.TestimonialsSection}>
<div className={styles.TestimonialsWrapper}>
<div className={styles.pageSubHeader}>
Some testimonials from our users
</div>
<div className={styles.testimonialsCarouselWrapper}>
<div id="myCarousel" className={'carousel slide ' + styles.testimonialsCarousel} data-ride="carousel" data-interval="false">
<div className={styles.quoteImg + ' ' + styles.quoteLeft}>
<img className={'img-responsive'} src={quoteLeft} alt={'Quote left'} />
</div>
<div className={styles.quoteImg + ' ' + styles.quoteright}>
<img className={'img-responsive'} src={quoteRight} alt={'Quote right'} />
</div>
<div className={'carousel-inner ' + styles.carouselInner}>
<div className={'item active ' + styles.carouselInnerItems}>
<div className={'col-md-6 col-sm-6 col-xs-12'}>
<div className={styles.indivRectBox}>
<div className={styles.quotes}>
</div>
<div className={styles.pageDescription}>
<a href="https://twitter.com/eveporcello" target="_blank" rel="noopener noreferrer">Eve Porcello, Instructor at Egghead.io</a>
</div>
<div className={styles.pageDescriptionSmall}>
This is one of the best tutorials I have seen for getting started with GraphQL and React. This is an incredible roadmap for learning these concepts in a linear and digestible way. If you are a React developer who is curious about Hasura and GraphQL, this is the place to start.
</div>
</div>
</div>
<div className={'col-md-6 col-sm-6 col-xs-12'}>
<div className={styles.indivRectBox}>
<div className={styles.quotes}>
<img className={'img-responsive'} src={twitter} alt={'twitter'} />
</div>
<div className={styles.pageDescription}>
<a href="https://twitter.com/raymondcamden/status/1131570271624802304" target="_blank" rel="noopener noreferrer">Raymond Camden, DevRel at American Express</a>
</div>
<div className={styles.pageDescriptionSmall}>
Damn, a free 2 hour course on GraphQL and <a href="https://twitter.com/vuejs" target="_blank" rel="noopener noreferrer">@vuejs</a> - <a href="https://learn.hasura.io/graphql/vue/introduction" target="_blank" rel="noopener noreferrer">https://learn.hasura.io/graphql/vue/introduction</a>. I can't wait to go through this! (When I can escape meeting hell.)
</div>
</div>
</div>
<div className={'col-md-6 col-sm-6 col-xs-12 visible-xs'}>
<div className={styles.indivRectBox}>
<div className={styles.quotes}>
<img className={'img-responsive'} src={twitter} alt={'twitter'} />
</div>
<div className={styles.pageDescription}>
<a href="https://twitter.com/themccallister/status/1127987752434376706" target="_blank" rel="noopener noreferrer">Jason M, Software Engineer</a>
</div>
<div className={styles.pageDescriptionSmall}>
Great introduction to <a href="https://twitter.com/hashtag/GraphQL?src=hash" target="_blank" rel="noopener noreferrer">#GraphQL</a> and covers <a href="https://twitter.com/HasuraHQ" target="_blank" rel="noopener noreferrer">@HasuraHQ</a>. If youre new to either its a good read.
</div>
</div>
</div>
<div className={'col-md-6 col-sm-6 col-xs-12 visible-xs'}>
<div className={styles.indivRectBox}>
<div className={styles.quotes}>
<img className={'img-responsive'} src={twitter} alt={'twitter'} />
</div>
<div className={styles.pageDescription}>
<a href="https://twitter.com/kevinsimper/status/1129757964812869632" target="_blank" rel="noopener noreferrer">Kevin Simper, CopenhagenJS Organiser</a>
</div>
<div className={styles.pageDescriptionSmall}>
Use <a href="https://twitter.com/HasuraHQ" target="_blank" rel="noopener noreferrer">@hasurahq</a> to get a production ready self hosted graphql api for a postgres db, see their video course
</div>
</div>
</div>
<div className={'col-md-6 col-sm-6 col-xs-12 visible-xs'}>
<div className={styles.indivRectBox}>
<div className={styles.quotes}>
<img className={'img-responsive'} src={twitter} alt={'Twitter'} />
</div>
<div className={styles.pageDescription}>
<a href="https://twitter.com/GNUmanth/status/1129602954309193728" target="_blank" rel="noopener noreferrer">Hemanth, PayPal</a>
</div>
<div className={styles.pageDescriptionSmall}>
<a href="https://learn.hasura.io/graphql/react" target="_blank" rel="noopener noreferrer">learn.hasura.io/graphql/react</a> <a href="https://twitter.com/hashtag/GraphQL?src=hash" target="_blank" rel="noopener noreferrer">#GraphQL</a> course for <a href="https://twitter.com/hashtag/react?src=hash" target="_blank" rel="noopener noreferrer">#react</a> peeps is very well done by <a href="https://twitter.com/HasuraHQ" target="_blank" rel="noopener noreferrer">@HasuraHQ</a> 👌🤘
</div>
</div>
</div>
<div className={'col-md-6 col-sm-6 col-xs-12 visible-xs'}>
<div className={styles.indivRectBox}>
<div className={styles.quotes}>
<img className={'img-responsive'} src={twitter} alt={'twitter'} />
</div>
<div className={styles.pageDescription}>
<a href="https://twitter.com/cem2ran/status/1129782849958305795" target="_blank" rel="noopener noreferrer">Cem, React Native Engineer at Lenus.io</a>
</div>
<div className={styles.pageDescriptionSmall}>
I've heard great things about Hasura and also this training material
</div>
</div>
</div>
<div className={'col-md-6 col-sm-6 col-xs-12 visible-xs'}>
<div className={styles.indivRectBox}>
<div className={styles.quotes}>
<img className={'img-responsive'} src={twitter} alt={'twitter'} />
</div>
<div className={styles.pageDescription}>
<a href="https://twitter.com/MikhailSheen/status/1132524526909165570" target="_blank" rel="noopener noreferrer">Mikhail Sheen, Web Developer</a>
</div>
<div className={styles.pageDescriptionSmall}>
I just completed this GraphQL course for React developers by @HasuraHQ. Check it out here -
<a href="https://learn.hasura.io/graphql/react" target="_blank" rel="noopener noreferrer">https://learn.hasura.io/graphql/react</a> <p>That was awesome time spending.</p>
<a href="https://twitter.com/hashtag/GraphQL?src=hash" target="_blank" rel="noopener noreferrer">#GraphQL</a> <a href="https://twitter.com/hashtag/reactjs?src=hash" target="_blank" rel="noopener noreferrer">#reactjs</a> <a href="https://twitter.com/hashtag/react?src=hash" target="_blank" rel="noopener noreferrer">#react</a>
</div>
</div>
</div>
<div className={'col-md-6 col-sm-6 col-xs-12 visible-xs'}>
<div className={styles.indivRectBox}>
<div className={styles.quotes}>
<img className={'img-responsive'} src={twitter} alt={'twitter'} />
</div>
<div className={styles.pageDescription}>
<a href="https://twitter.com/s_ibylle/status/1138143802831585280" target="_blank" rel="noopener noreferrer">Sibylle, Front-End Dev @brandung</a>
</div>
<div className={styles.pageDescriptionSmall}>
This is a really great tutorial for people keen to learn more about GraphQL <span role="img" aria-labelledby="rocket">🚀</span> I just went through the React one, but they have tutorials for Vue, iOS and RN too <span role="img" aria-labelledby="heart">💙</span> Thanks for the folk at Hasura for putting that together <a href="https://twitter.com/hashtag/2Hours2GraphQL?src=hash" target="_blank" rel="noopener noreferrer">#2Hours2GraphQL</a>
</div>
</div>
</div>
</div>
<div className={'item hidden-xs ' + styles.carouselInnerItems}>
<div className={'col-md-6 col-sm-6 col-xs-12'}>
<div className={styles.indivRectBox}>
<div className={styles.quotes}>
<img className={'img-responsive'} src={twitter} alt={'twitter'} />
</div>
<div className={styles.pageDescription}>
<a href="https://twitter.com/themccallister/status/1127987752434376706" target="_blank" rel="noopener noreferrer">Jason M, Software Engineer</a>
</div>
<div className={styles.pageDescriptionSmall}>
Great introduction to <a href="https://twitter.com/hashtag/GraphQL?src=hash" target="_blank" rel="noopener noreferrer">#GraphQL</a> and covers <a href="https://twitter.com/HasuraHQ" target="_blank" rel="noopener noreferrer">@HasuraHQ</a>. If youre new to either its a good read.
</div>
</div>
</div>
<div className={'col-md-6 col-sm-6 col-xs-12'}>
<div className={styles.indivRectBox}>
<div className={styles.quotes}>
<img className={'img-responsive'} src={twitter} alt={'twitter'} />
</div>
<div className={styles.pageDescription}>
<a href="https://twitter.com/kevinsimper/status/1129757964812869632" target="_blank" rel="noopener noreferrer">Kevin Simper, CopenhagenJS Organiser</a>
</div>
<div className={styles.pageDescriptionSmall}>
Use <a href="https://twitter.com/HasuraHQ" target="_blank" rel="noopener noreferrer">@hasurahq</a> to get a production ready self hosted graphql api for a postgres db, see their video course
</div>
</div>
</div>
</div>
<div className={'item hidden-xs ' + styles.carouselInnerItems}>
<div className={'col-md-6 col-sm-6 col-xs-12'}>
<div className={styles.indivRectBox}>
<div className={styles.quotes}>
<img className={'img-responsive'} src={twitter} alt={'Twitter'} />
</div>
<div className={styles.pageDescription}>
<a href="https://twitter.com/GNUmanth/status/1129602954309193728" target="_blank" rel="noopener noreferrer">Hemanth, PayPal</a>
</div>
<div className={styles.pageDescriptionSmall}>
<a href="https://learn.hasura.io/graphql/react" target="_blank" rel="noopener noreferrer">learn.hasura.io/graphql/react</a> <a href="https://twitter.com/hashtag/GraphQL?src=hash" target="_blank" rel="noopener noreferrer">#GraphQL</a> course for <a href="https://twitter.com/hashtag/react?src=hash" target="_blank" rel="noopener noreferrer">#react</a> peeps is very well done by <a href="https://twitter.com/HasuraHQ" target="_blank" rel="noopener noreferrer">@HasuraHQ</a> 👌🤘
</div>
</div>
</div>
<div className={'col-md-6 col-sm-6 col-xs-12'}>
<div className={styles.indivRectBox}>
<div className={styles.quotes}>
<img className={'img-responsive'} src={twitter} alt={'twitter'} />
</div>
<div className={styles.pageDescription}>
<a href="https://twitter.com/cem2ran/status/1129782849958305795" target="_blank" rel="noopener noreferrer">Cem, React Native Engineer at Lenus.io</a>
</div>
<div className={styles.pageDescriptionSmall}>
I've heard great things about Hasura and also this training material
</div>
</div>
</div>
</div>
<div className={'item hidden-xs ' + styles.carouselInnerItems}>
<div className={'col-md-6 col-sm-6 col-xs-12'}>
<div className={styles.indivRectBox}>
<div className={styles.quotes}>
<img className={'img-responsive'} src={twitter} alt={'twitter'} />
</div>
<div className={styles.pageDescription}>
<a href="https://twitter.com/MikhailSheen/status/1132524526909165570" target="_blank" rel="noopener noreferrer">Mikhail Sheen, Web Developer</a>
</div>
<div className={styles.pageDescriptionSmall}>
I just completed this GraphQL course for React developers by @HasuraHQ. Check it out here -
<a href="https://learn.hasura.io/graphql/react" target="_blank" rel="noopener noreferrer">https://learn.hasura.io/graphql/react</a> <p>That was awesome time spending.</p>
<a href="https://twitter.com/hashtag/GraphQL?src=hash" target="_blank" rel="noopener noreferrer">#GraphQL</a> <a href="https://twitter.com/hashtag/reactjs?src=hash" target="_blank" rel="noopener noreferrer">#reactjs</a> <a href="https://twitter.com/hashtag/react?src=hash" target="_blank" rel="noopener noreferrer">#react</a>
</div>
</div>
</div>
<div className={'col-md-6 col-sm-6 col-xs-12'}>
<div className={styles.indivRectBox}>
<div className={styles.quotes}>
<img className={'img-responsive'} src={twitter} alt={'twitter'} />
</div>
<div className={styles.pageDescription}>
<a href="https://twitter.com/s_ibylle/status/1138143802831585280" target="_blank" rel="noopener noreferrer">Sibylle, Front-End Dev @brandung</a>
</div>
<div className={styles.pageDescriptionSmall}>
This is a really great tutorial for people keen to learn more about GraphQL <span role="img" aria-labelledby="rocket">🚀</span> I just went through the React one, but they have tutorials for Vue, iOS and RN too <span role="img" aria-labelledby="heart">💙</span> Thanks for the folk at Hasura for putting that together <a href="https://twitter.com/hashtag/2Hours2GraphQL?src=hash" target="_blank" rel="noopener noreferrer">#2Hours2GraphQL</a>
</div>
</div>
</div>
</div>
</div>
<a className={'left carousel-control hidden-xs ' + styles.carouselControl} href="#myCarousel" data-slide="prev">
{/*
<span className="glyphicon glyphicon-chevron-left"></span>
*/}
<span className="sr-only">Previous</span>
<img className={'img-responsive'} src={LeftArrow} alt={'Left arrow'} />
</a>
<a className={'right carousel-control hidden-xs ' + styles.carouselControl} href="#myCarousel" data-slide="next">
{/*
<span className="glyphicon glyphicon-chevron-right"></span>
<span className="sr-only">Next</span>
*/}
<img className={'img-responsive'} src={RightArrow} alt={'Right arrow'} />
</a>
</div>
</div>
<div className={'whiteBgColor commonSectionWrapper'}>
<div className={'container noPadd'}>
<div className={'testimoialsWrapper wd80'}>
<div className={'sectionHeader'}>
Testimonials
</div>
<div className={'purpleLineSeperator'}>
</div>
<div className={'testimonialListWrapper'}>
{listWrapper}
</div>
</div>
</div>

View File

@ -15,7 +15,7 @@ class TopBanner extends React.Component {
<div className={'whiteLineSeperator'}>
</div>
<div className={'sectionDescription'}>
With these <a href="https://github.com/hasura/graphql-engine/tree/master/community/learn">open-source</a> tutorials, you will move from the basics of GraphQL to building a real-time application in 2 hours
With these <a href="https://github.com/hasura/graphql-engine/tree/master/community/learn">open-source</a> community maintained tutorials, you will move from the basics of GraphQL to building a real-time application in 2 hours
</div>
</div>
<div className={'col-md-6 col-sm-6 col-xs-12 noPadd'}>

View File

@ -33,7 +33,7 @@ class WillLearn extends React.Component {
)
})
return (
<div className={'whiteBgColor commonSectionWrapper'}>
<div className={'lightGrayBgColor commonSectionWrapper'}>
<div className={'container noPadd'}>
<div className={'willLearnWrapper'}>
<div className={'col-md-12'}>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,21 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="80.92" height="78" viewBox="0 0 80.92 78">
<defs>
<style>
.cls-1{fill:url(#linear-gradient)}.cls-2{filter:url(#quote)}
</style>
<linearGradient id="linear-gradient" x1=".5" x2=".5" y2="1" gradientUnits="objectBoundingBox">
<stop offset="0" stop-color="#2a0685"/>
<stop offset="1" stop-color="#6a096a"/>
</linearGradient>
<filter id="quote" width="80.92" height="78" x="0" y="0" filterUnits="userSpaceOnUse">
<feOffset dy="3"/>
<feGaussianBlur result="blur" stdDeviation="3"/>
<feFlood flood-opacity=".161"/>
<feComposite in2="blur" operator="in"/>
<feComposite in="SourceGraphic"/>
</filter>
</defs>
<g class="cls-2">
<path id="quote-2" d="M14.6 32.114v5.065h12.655v27.253H0V32.114c0-10.285 2.96-17.922 8.8-22.7 4.037-3.305 9.148-4.981 15.19-4.981v14.6c-3.284 0-9.39 0-9.39 13.081zm45.052-13.081v-14.6c-6.042 0-11.152 1.676-15.19 4.981-5.836 4.778-8.8 12.415-8.8 22.7v32.318H62.92V37.179H50.266v-5.065c0-13.081 6.106-13.081 9.386-13.081z" class="cls-1" data-name="quote" transform="translate(9 1.57)"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,21 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="80.92" height="78" viewBox="0 0 80.92 78">
<defs>
<style>
.cls-1{fill:url(#linear-gradient)}.cls-2{filter:url(#quote)}
</style>
<linearGradient id="linear-gradient" x1=".5" x2=".5" y2="1" gradientUnits="objectBoundingBox">
<stop offset="0" stop-color="#260687"/>
<stop offset="1" stop-color="#6a096a"/>
</linearGradient>
<filter id="quote" width="80.92" height="78" x="0" y="0" filterUnits="userSpaceOnUse">
<feOffset dy="3"/>
<feGaussianBlur result="blur" stdDeviation="3"/>
<feFlood flood-opacity=".161"/>
<feComposite in2="blur" operator="in"/>
<feComposite in="SourceGraphic"/>
</filter>
</defs>
<g class="cls-2">
<path id="quote-2" d="M48.319 32.114v5.065H35.665v27.253H62.92V32.114c0-10.285-2.959-17.921-8.8-22.7-4.037-3.305-9.148-4.981-15.19-4.981v14.6c3.283 0 9.389 0 9.389 13.081zM3.268 19.033v-14.6c6.042 0 11.152 1.676 15.19 4.981 5.836 4.778 8.8 12.415 8.8 22.7v32.318H0V37.179h12.653v-5.065c0-13.081-6.105-13.081-9.385-13.081z" class="cls-1" data-name="quote" transform="translate(9 1.57)"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1 +0,0 @@
<svg height="27" viewBox="0 0 35 27" width="35" xmlns="http://www.w3.org/2000/svg"><path d="m16.994 7.182.076 1.168-1.264-.143c-4.603-.547-8.624-2.407-12.038-5.529l-1.668-1.55-.43 1.145c-.91 2.55-.329 5.243 1.568 7.054 1.012 1.001.784 1.144-.961.549-.607-.191-1.138-.334-1.189-.263-.177.167.43 2.336.91 3.194.658 1.192 1.999 2.36 3.466 3.05l1.239.549-1.467.024c-1.416 0-1.467.024-1.315.524.506 1.55 2.504 3.194 4.729 3.909l1.568.5-1.366.763c-2.023 1.096-4.4 1.716-6.777 1.763-1.139.024-2.075.121-2.075.191 0 .238 3.085 1.573 4.88 2.097 5.388 1.55 11.786.882 16.59-1.763 3.415-1.883 6.829-5.625 8.422-9.247.86-1.93 1.72-5.458 1.72-7.15 0-1.097.076-1.24 1.492-2.55.834-.763 1.618-1.597 1.77-1.836.253-.453.228-.453-1.062-.047-2.15.715-2.453.62-1.391-.453.784-.763 1.72-2.145 1.72-2.55 0-.072-.38.047-.81.262-.455.238-1.466.596-2.225.81l-1.366.405-1.239-.786c-.683-.43-1.644-.906-2.15-1.049-1.29-.334-3.262-.286-4.425.095-3.161 1.073-5.16 3.838-4.932 6.864z" fill="#55acee" fill-rule="evenodd"/></svg>

Before

Width:  |  Height:  |  Size: 998 B

View File

@ -2,6 +2,7 @@ import React from 'react';
import '../styles/styles.scss';
import Header from '../components/Header';
import TopBanner from '../components/TopBanner';
import Featured from '../components/Featured';
import Tutorials from '../components/Tutorials';
import WillLearn from '../components/WillLearn';
import SubscribeNewsletter from '../components/SubscribeNewsletter';
@ -14,6 +15,7 @@ class Index extends React.Component {
<Header/>
<TopBanner/>
<Tutorials/>
<Featured/>
<WillLearn/>
<Testimonials/>
<SubscribeNewsletter/>

View File

@ -15,6 +15,11 @@ body
width: 100%;
float: left;
}
.wd80
{
width: 80%;
margin: 0 auto;
}
.noPadd
{
padding-left: 0 !important;
@ -490,82 +495,82 @@ ul
}
.reactBg
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/react-purple.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/react-original.svg');
&:hover
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/react-original.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/react-purple.svg');
}
}
.vueBg
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/vue-purple.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/vue-original.svg');
&:hover
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/vue-original.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/vue-purple.svg');
}
}
.angularBg
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/angular-purple.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/angular-original.svg');
&:hover
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/angular-original.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/angular-purple.svg');
}
}
.elmBg
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/elm-purple.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/elm-original.jpg');
&:hover
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/elm-original.jpg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/elm-purple.svg');
}
}
.reBg
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/reasonml-purple.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/reasonml-original.svg');
&:hover
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/reasonml-original.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/reasonml-purple.svg');
}
}
.hasuraBg
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/hasura-purple.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/hasura-original.svg');
&:hover
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/hasura-original.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/hasura-purple.svg');
}
}
.postgresBg
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/postgres-purple.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/postgres-original.svg');
&:hover
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/postgres-original.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/postgres-purple.svg');
}
}
.iosBg
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/ios-purple.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/ios-original.png');
&:hover
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/ios-original.png');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/ios-purple.svg');
}
}
.androidBg
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/android-purple.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/android-original.svg');
&:hover
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/android-original.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/android-purple.svg');
}
}
.flutterBg
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/flutter-purple.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/flutter-original.svg');
&:hover
{
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/flutter-original.svg');
background-image: url('https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/flutter-purple.svg');
}
}
.reactDisableBg
@ -999,6 +1004,112 @@ ul
clear: both;
font-size: 12px;
}
.testimoialsWrapper
{
.sectionHeader
{
text-align: center;
padding-bottom: 20px;
}
.purpleLineSeperator
{
margin: 0 auto;
}
.testimonialListWrapper
{
.testimonialList
{
padding: 40px 0;
border-bottom: 1px solid #cbcbcb;
.testimonialContent
{
font-family: 'Raleway';
font-size: 28px;
font-weight: bold;
color: #606060;
line-height: 1.36;
padding: 24px 0;
}
.authorWrapper
{
display: flex;
align-items: center;
.authorImg
{
img
{
width: 90px;
height: 90px;
border-radius: 50%;
}
}
.author
{
padding-left: 24px;
.name
{
font-family: 'Roboto';
font-size: 18px;
font-weight: bold;
line-height: 1.33;
color: #1f88e5;
padding-bottom: 4px;
a
{
color: #1f88e5;
}
a:hover
{
text-decoration: none;
}
}
.designation
{
font-family: 'Roboto';
font-size: 16px;
font-weight: normal;
color: #303030;
line-height: 1.31;
a
{
color: #1f88e5;
}
a:hover
{
text-decoration: none;
}
}
}
}
}
}
}
.featuredWrapper
{
.sectionHeader
{
text-align: center;
padding-bottom: 20px;
}
.purpleLineSeperator
{
margin: 0 auto;
}
.featuredIconWrapper
{
text-align: center;
padding-top: 60px;
.featuredIcon
{
display: inline-block;
padding: 0 35px;
img
{
max-height: 90px;
}
}
}
}
@media (max-width: 767px)
{
.commonSectionWrapper
@ -1245,6 +1356,76 @@ ul
{
padding-top: 30px;
}
.wd80
{
width: 100%;
}
.testimoialsWrapper
{
padding: 0 15px;
.testimonialListWrapper
{
.testimonialList
{
.quotes
{
img
{
width: 30px;
}
}
.testimonialContent
{
font-size: 16px;
padding: 15px 0;
line-height: 1.6;
a
{
word-break: break-all;
}
}
.authorWrapper
{
.authorImg
{
img
{
width: 75px;
height: 75px;
}
}
.author
{
padding-left: 15px;
.name
{
font-size: 16px;
}
.designation
{
font-size: 14px;
}
}
}
}
}
}
.featuredWrapper
{
.featuredIconWrapper
{
padding-top: 40px;
.featuredIcon
{
padding: 0 10px;
img
{
max-height: 50px;
max-width: 75px;
}
}
}
}
}
@media (min-width: 768px) and (max-width: 991px)
{
@ -1348,4 +1529,17 @@ ul
{
padding-top: 30px;
}
.testimoialsWrapper
{
.testimonialListWrapper
{
.testimonialList
{
.testimonialContent
{
font-size: 20px;
}
}
}
}
}

View File

@ -37,6 +37,14 @@ data:
/graphql/reason-react-apollo/boilerplate.zip https://graphql-engine-cdn.hasura.io/learn-hasura/boilerplates/reason-react-apollo/boilerplate.zip
}
redir 301 {
/graphql/flutter-graphql/boilerplate.zip https://graphql-engine-cdn.hasura.io/learn-hasura/boilerplates/flutter-graphql/boilerplate.zip
}
redir 301 {
/graphql/flutter-graphql/ /graphql/flutter-graphql/introduction
}
redir 301 {
/graphql/reason-react-apollo/ /graphql/reason-react-apollo/introduction
}
@ -121,6 +129,8 @@ data:
proxy /graphql/reason-react-apollo reason-react-apollo
proxy /graphql/flutter-graphql flutter-graphql
proxy /graphql hasura/v1/graphql {
without /graphql
websocket

View File

@ -0,0 +1,50 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: flutter-graphql
name: flutter-graphql
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: flutter-graphql
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 100%
template:
metadata:
labels:
app: flutter-graphql
spec:
containers:
- image: hasura/base-git-image:0.7
imagePullPolicy: IfNotPresent
name: flutter-graphql
ports:
- containerPort: 8080
protocol: TCP
readinessProbe:
httpGet:
path: /graphql/flutter-graphql/introduction
port: 8080
---
apiVersion: v1
kind: Service
metadata:
labels:
app: flutter-graphql
name: flutter-graphql
namespace: default
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: flutter-graphql
type: ClusterIP

View File

@ -69,6 +69,11 @@ spec:
name: reason-react-apollo
path: ./community/learn/graphql-tutorials/tutorials/reason-react-apollo/tutorial-site
name: reason-react-apollo
- containers:
- dockerfile: ./community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site/Dockerfile
name: flutter-graphql
path: ./community/learn/graphql-tutorials/tutorials/flutter-graphql/tutorial-site
name: flutter-graphql
manifests:
helm: {}
path: ./community/learn/graphql-tutorials/manifests

View File

@ -1,7 +1,7 @@
FROM node:carbon
# update this line when gatsby-gitbook-starter repo changes
RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"'
RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"'
# Install global dependencies
RUN npm -g install gatsby-cli

View File

@ -1,7 +1,7 @@
FROM node:carbon
# update this line when gatsby-gitbook-starter repo changes
RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"'
RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"'
# Install global dependencies
RUN npm -g install gatsby-cli

View File

@ -5,8 +5,9 @@ const config = {
"gaTrackingId": "UA-59768903-1"
},
"header": {
"logo": "https://graphql-engine-cdn.hasura.io/img/hasura_icon_white.svg",
"title": "/ graphql / android",
"logo": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/logo.png",
"logoLink": "https://learn.hasura.io",
"title": "<a href='https://learn.hasura.io'>/ graphql </a><a href='https://learn.hasura.io/graphql/android'>/ android</a>",
"githubUrl": "https://github.com/hasura/graphql-engine",
"helpUrl": "https://discordapp.com/invite/vBPpJkS",
"tweetText": "Check out this GraphQL course for Android Developers by @HasuraHQ https://learn.hasura.io/graphql/android",
@ -37,7 +38,9 @@ const config = {
"text": "GraphQL Docs",
"link": "https://graphql.org/learn"
}
]
],
"frontline": false,
"ignoreIndex": true
},
"siteMetadata": {
"title": "2 hour GraphQL course for Android Developers | Hasura",

View File

@ -8,7 +8,7 @@ import GithubLink from '../src/GithubLink.js'
Apollo gives a neat abstraction layer and an interface to your GraphQL server. You don't need to worry about constructing your queries with request body, headers and options, that you might have done with `OkHttp` or `Retrofit` say. You can directly write queries and mutations in GraphQL and they will automatically be sent to your server via your apollo client instance.
### Android Apollo Installation
## Android Apollo Installation
Let's get started by adding apollo client & peer graphql dependenices to the project:
- The latest gradle plugin version is [ ![Download](https://api.bintray.com/packages/apollographql/android/apollo-gradle-plugin/images/download.svg) ](https://bintray.com/apollographql/android/apollo-gradle-plugin/_latestVersion). We will use the latest snapshot.
@ -44,7 +44,7 @@ dependencies {
apply plugin: 'com.apollographql.android'
```
\*\*Note: The Android Plugin must be applied before the Apollo plugin
**Note:** The Android Plugin must be applied before the Apollo plugin
### Adding code generation
@ -59,7 +59,7 @@ dependencies {
- Now create a `graphql`inside the `main`directory and create new directory structure like `graphql/com/hasura/todo`so that the **Apollo plugin can generate java classes with valid package**.
### Create `.graphql` files with your queries or mutations
### Create .graphql files with your queries or mutations
Apollo generates code from queries and mutations contained in `.graphql` files in your target.
@ -94,7 +94,7 @@ implementation 'javax.annotation:jsr250-api:1.0'
- Compile your project to have Apollo generate the appropriate Java classes with nested classes for reading from the network response. In the sample project, a `GetAllTodosQuery` Java class is created here `app/build/generated/source/apollo/classes/com.hasura.todo/`
\*\*Note: This is an autogenerated file by Apollo and should not be changed manually
**Note:** This is an autogenerated file by Apollo and should not be changed manually
- Before we start making requests, we need to add couple of more dependencies in app's build.gradle. OkHttp for networking interface

View File

@ -1,5 +1,5 @@
---
title: "Course introduction"
title: "Course Introduction"
metaTitle: "Course Introduction | GraphQL Android Apollo Tutorial"
metaDescription: "A powerful and concise tutorial that will introduce you to GraphQL and integrating GraphQL into your Android app with Apollo and Kotlin, in the shortest amount of time possible."
---
@ -9,7 +9,6 @@ This course is a concise and powerful introduction to GraphQL for android develo
Weve structured this course to cover fundamental concepts of both GraphQL and using GraphQL in Android, in the shortest amount of time possible. The course is light on opinions so that once you grok the fundamentals you can go on to choose your favourite tools and tailor your workflow.
## Key topics and takeways:
- GraphQL vs REST
- GraphQL queries, mutations, subscriptions
- Setting up a GraphQL client with Apollo
@ -21,24 +20,26 @@ Weve structured this course to cover fundamental concepts of both GraphQL and
- Building a real-time feed with notifications using mutations and subscriptions
## What will be building?
We will be building a realtime todo app using authenticated GraphQL APIs.
Try this deployed version of the frontend app to see what we'll be building: https://learn-hasura-todo-app.netlify.com/
This is built on React but the functionality will be the same for android.
## Will this course teach android concepts as well?
## Will this course teach Android concepts as well?
No, we will be simulating a scenario where we already have a
GraphQL API and the basic UI of a android app built. Our task in this
scenario is to integrate the GraphQL APIs into our android app to build
a complete and working app.
## What do I need to take this tutorial?
You need to have npm/yarn & node 8+ running.
## How long will this tutorial take?
Less than 2 hours
## Other courses
**Frontend**: GraphQL for: [Vue](https://learn.hasura.io/graphql/vue), [React Native](https://learn.hasura.io/graphql/react-native), [iOS](https://learn.hasura.io/graphql/ios)
**Backend**: [Building a realtime GraphQL backend with Hasura](https://learn.hasura.io/graphql/hasura) in 30 mins (ideal for frontend, backend or fullstack developers)

View File

@ -1,7 +1,7 @@
FROM node:carbon
# update this line when gatsby-gitbook-starter repo changes
RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"'
RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"'
# Install global dependencies
RUN npm -g install gatsby-cli

View File

@ -1,7 +1,7 @@
FROM node:carbon
# update this line when gatsby-gitbook-starter repo changes
RUN sh -c 'echo -e "Updated at: 2019-06-03 19:00:00 IST"'
RUN sh -c 'echo -e "Updated at: 2019-07-30 19:00:00 IST"'
# Install global dependencies
RUN npm -g install gatsby-cli

View File

@ -5,8 +5,9 @@ const config = {
"gaTrackingId": "UA-59768903-1"
},
"header": {
"logo": "https://graphql-engine-cdn.hasura.io/img/hasura_icon_white.svg",
"title": "/ graphql / elm-graphql",
"logo": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/homepage/logo.png",
"logoLink": "https://learn.hasura.io",
"title": "<a href='https://learn.hasura.io'>/ graphql </a><a href='https://learn.hasura.io/graphql/elm-graphql'>/ elm-graphql</a>",
"githubUrl": "https://github.com/hasura/graphql-engine",
"helpUrl": "https://discordapp.com/invite/vBPpJkS",
"tweetText": "Check out this GraphQL course for Elm developers by @HasuraHQ https://learn.hasura.io/graphql/elm-graphql",
@ -17,17 +18,17 @@ const config = {
},
"sidebar": {
"forcedNavOrder": [
"/introduction",
"/introduction",
"/intro-to-graphql",
"/setup",
"/elm-graphql",
"/queries",
"/mutations-variables",
"/apollo-client",
"/apollo-client",
"/subscriptions",
"/realtime-feed",
"/what-next"
],
],
"links": [
{
"text": "Hasura Docs",
@ -37,14 +38,16 @@ const config = {
"text": "GraphQL Docs",
"link": "https://graphql.org/learn"
}
]
],
"frontline": false,
"ignoreIndex": true
},
"siteMetadata": {
"title": "2 hour GraphQL course for Elm developers | Hasura",
"description": "A concise and powerful tutorial that covers fundamental concepts of both GraphQL and using GraphQL in Elm",
"ogImage": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/social-media/twitter-card-elm.jpg",
"docsLocation": "https://github.com/hasura/graphql-engine/tree/master/community/learn/graphql-tutorials/tutorials/elm-graphql/tutorial-site/content",
"favicon": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/graphql-elm/favicon.ico"
"favicon": "https://graphql-engine-cdn.hasura.io/learn-hasura/assets/graphql-elm/favicon.ico"
},
};

View File

@ -40,7 +40,7 @@ You need to have elm 0.19.0, npm/yarn & node 8+ running.
## How long will this tutorial take?
Less than 2 hours
## Other courses:
## Other courses
**Frontend**: GraphQL for: [React](https://learn.hasura.io/graphql/react), [Vue](https://learn.hasura.io/graphql/vue), [React Native](https://learn.hasura.io/graphql/react-native), [iOS](https://learn.hasura.io/graphql/ios)

View File

@ -234,7 +234,7 @@ Lets add it to our update function to update the models appropriately
```
### Update `loadLatestPublicTodo` and `loadOldPublicTodos`
### Update loadLatestPublicTodo and loadOldPublicTodos
Lets update our render functions to invoke relevant actions on click

View File

@ -0,0 +1,73 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.packages
.pub-cache/
.pub/
/build/
# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
**/android/key.properties
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages

View File

@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 362b999b90d53859aa7b926a59c970f3ea31abf4
channel: dev
project_type: app

View File

@ -0,0 +1,16 @@
# app_boilerplate
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

View File

@ -0,0 +1,61 @@
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 28
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.app_boilerplate"
minSdkVersion 16
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

View File

@ -0,0 +1,7 @@
## Flutter wrapper
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }

View File

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app_boilerplate">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@ -0,0 +1,34 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app_boilerplate">
<uses-permission android:name="android.permission.INTERNET" />
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="app_boilerplate"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -0,0 +1,13 @@
package com.example.app_boilerplate;
import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
}
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
</resources>

View File

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app_boilerplate">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@ -0,0 +1,29 @@
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@ -0,0 +1,4 @@
org.gradle.jvmargs=-Xmx1536M
android.enableJetifier=true
android.useAndroidX=true

View File

@ -0,0 +1,6 @@
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip

View File

@ -0,0 +1,15 @@
include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
</dict>
</plist>

View File

@ -0,0 +1,2 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -0,0 +1,2 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

View File

@ -0,0 +1,72 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def parse_KV_file(file, separator='=')
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
end
pods_ary = []
skip_line_start_symbols = ["#", "/"]
File.foreach(file_abs_path) { |line|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
plugin = line.split(pattern=separator)
if plugin.length == 2
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
pods_ary.push({:name => podname, :path => podpath});
else
puts "Invalid plugin specification: #{line}"
end
}
return pods_ary
end
target 'Runner' do
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
system('rm -rf .symlinks')
system('mkdir -p .symlinks/plugins')
# Flutter Pods
generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
if generated_xcode_build_settings.empty?
puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first."
end
generated_xcode_build_settings.map { |p|
if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
symlink = File.join('.symlinks', 'flutter')
File.symlink(File.dirname(p[:path]), symlink)
pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
end
}
# Plugin Pods
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.map { |p|
symlink = File.join('.symlinks', 'plugins', p[:name])
File.symlink(p[:path], symlink)
pod p[:name], :path => File.join(symlink, 'ios')
}
end
# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
install! 'cocoapods', :disable_input_output_paths => true
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end

View File

@ -0,0 +1,22 @@
PODS:
- Flutter (1.0.0)
- shared_preferences (0.0.1):
- Flutter
DEPENDENCIES:
- Flutter (from `.symlinks/flutter/ios`)
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
EXTERNAL SOURCES:
Flutter:
:path: ".symlinks/flutter/ios"
shared_preferences:
:path: ".symlinks/plugins/shared_preferences/ios"
SPEC CHECKSUMS:
Flutter: 58dd7d1b27887414a370fcccb9e645c08ffd7a6a
shared_preferences: 1feebfa37bb57264736e16865e7ffae7fc99b523
PODFILE CHECKSUM: 7fb83752f59ead6285236625b82473f90b1cb932
COCOAPODS: 1.7.3

View File

@ -0,0 +1,571 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
B2A1B942C7567EA1E192F576 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69F5F66A71A9272B941370B7 /* libPods-Runner.a */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
009B69F0F11A836865C26587 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
69F5F66A71A9272B941370B7 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
7243B9F2463C76C8A9F67B79 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D49B8277A02C5FB9D47F6C60 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
B2A1B942C7567EA1E192F576 /* libPods-Runner.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
2E89F3FDCF7059D26DB27B4E /* Frameworks */ = {
isa = PBXGroup;
children = (
69F5F66A71A9272B941370B7 /* libPods-Runner.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
34912711BAAE182FA08750E7 /* Pods */ = {
isa = PBXGroup;
children = (
7243B9F2463C76C8A9F67B79 /* Pods-Runner.debug.xcconfig */,
009B69F0F11A836865C26587 /* Pods-Runner.release.xcconfig */,
D49B8277A02C5FB9D47F6C60 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B80C3931E831B6300D905FE /* App.framework */,
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEBA1CF902C7004384FC /* Flutter.framework */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
34912711BAAE182FA08750E7 /* Pods */,
2E89F3FDCF7059D26DB27B4E /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
);
path = Runner;
sourceTree = "<group>";
};
97C146F11CF9000F007C117D /* Supporting Files */ = {
isa = PBXGroup;
children = (
97C146F21CF9000F007C117D /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
885AE27C3CC997A8D697998C /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
D916C489DDDC3AE07EB82305 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0910;
ORGANIZATIONNAME = "The Chromium Authors";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
};
885AE27C3CC997A8D697998C /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
D916C489DDDC3AE07EB82305 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
97C146F31CF9000F007C117D /* main.m in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = S8QB4VV633;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.appBoilerplate;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.appBoilerplate;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.appBoilerplate;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0910"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,6 @@
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : FlutterAppDelegate
@end

View File

@ -0,0 +1,13 @@
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end

View File

@ -0,0 +1,122 @@
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,5 @@
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>app_boilerplate</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
</dict>
</plist>

View File

@ -0,0 +1,9 @@
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char* argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

View File

@ -0,0 +1,46 @@
import 'package:app_boilerplate/components/custom_button.dart';
import 'package:flutter/material.dart';
class AddTask extends StatelessWidget {
//final TodoList todoList;
final Function onAdd;
const AddTask({Key key, this.onAdd}) : super(key: key);
@override
Widget build(BuildContext context) {
TextEditingController _controller = TextEditingController();
return Container(
child: Padding(
padding: const EdgeInsets.all(18.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: TextFormField(
controller: _controller,
decoration: InputDecoration(
labelText: "Add task",
border: OutlineInputBorder(),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: CustomButton(
width: 90,
height: 50,
onTap: () {
onAdd(_controller.text);
_controller.clear();
FocusScope.of(context).requestFocus(new FocusNode());
},
text: "Add",
),
)
],
),
),
);
}
}

View File

@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
class CustomButton extends StatelessWidget {
final Function onTap;
final String text;
final double height;
final double width;
CustomButton({
Key key,
@required this.onTap,
@required this.text,
@required this.height,
@required this.width,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
width: width,
height: height,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(23), color: Colors.black),
child: Center(
child: Text(
text,
style: TextStyle(color: Colors.white),
),
),
),
);
}
}

View File

@ -0,0 +1,22 @@
import 'package:flutter/material.dart';
class FeedTile extends StatelessWidget {
final String username;
final String feed;
FeedTile({
Key key,
@required this.username,
@required this.feed,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Card(
child: ListTile(
title: Text(username),
subtitle: Text(feed),
),
);
}
}

View File

@ -0,0 +1,52 @@
import 'package:app_boilerplate/model/todo_item.dart';
import 'package:flutter/material.dart';
class TodoItemTile extends StatelessWidget {
final TodoItem item;
final Function delete;
final Function toggleIsCompleted;
TodoItemTile({
Key key,
@required this.item,
@required this.delete,
@required this.toggleIsCompleted,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Card(
child: ListTile(
contentPadding: EdgeInsets.all(0),
title: Text(item.task,
style: TextStyle(
decoration: item.isCompleted
? TextDecoration.lineThrough
: TextDecoration.none)),
leading: InkWell(
onTap: () {
toggleIsCompleted();
},
child: Container(
height: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Icon(!item.isCompleted
? Icons.radio_button_unchecked
: Icons.radio_button_checked),
),
),
trailing: InkWell(
onTap: () {
delete();
},
child: Container(
decoration: BoxDecoration(
border: Border(left: BorderSide(color: Colors.grey))),
width: 60,
height: double.infinity,
child: Icon(Icons.delete)),
),
),
),
);
}
}

View File

@ -0,0 +1,9 @@
import 'package:flutter/material.dart';
import 'package:toast/toast.dart';
class UtilFs {
static showToast(String message, BuildContext context) {
Toast.show(message, context,
duration: Toast.LENGTH_LONG, gravity: Toast.BOTTOM);
}
}

View File

@ -0,0 +1,19 @@
import 'package:app_boilerplate/model/feed_item.dart';
class FeedList {
List<FeedItem> list = [
FeedItem.fromElements("", "user1", "I'm user1"),
FeedItem.fromElements("", "user2", "I'm user2"),
FeedItem.fromElements("", "user3", "I'm user3"),
FeedItem.fromElements("", "user4", "I'm user4"),
FeedItem.fromElements("", "user5", "I'm user5"),
];
addFeed(String id, String username, String feed) {
list.add(
FeedItem.fromElements(id, username, feed),
);
}
}
FeedList feedList = new FeedList();

View File

@ -0,0 +1,5 @@
class OnlineList {
List<String> list = ["User1", "User3", "User5"];
}
OnlineList onlineList = new OnlineList();

View File

@ -0,0 +1,32 @@
import 'package:app_boilerplate/model/todo_item.dart';
class TodoList {
List<TodoItem> list = [];
int id = 0;
addTodo(String task) {
id++;
list.add(
TodoItem.fromElements(
id,
task,
false,
),
);
}
removeTodo(int id) {
list.removeWhere((item) => item.id == id);
}
toggleList(int id) {
int index = list.indexWhere((item) => item.id == id);
list[index].isCompleted = !list[index].isCompleted;
}
List<TodoItem> get activeList =>
list.where((item) => item.isCompleted == false).toList();
List<TodoItem> get completeList =>
list.where((item) => item.isCompleted == true).toList();
}
TodoList todoList = new TodoList();

View File

@ -0,0 +1,24 @@
import 'package:app_boilerplate/screens/dashboard.dart';
import 'package:app_boilerplate/screens/login.dart';
import 'package:app_boilerplate/screens/signup.dart';
import 'package:app_boilerplate/screens/splash.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final routes = <String, WidgetBuilder>{
"/login": (BuildContext context) => Login(),
"/dashboard": (BuildContext context) => Dashboard(),
"/signup": (BuildContext context) => Signup(),
};
return MaterialApp(
title: 'Hasura GraphQL Demo',
theme: ThemeData(primaryColor: Colors.black),
routes: routes,
home: Splash(),
);
}
}

View File

@ -0,0 +1,11 @@
class FeedItem {
String id = "";
String username = "";
String feed = "";
FeedItem.fromElements(String id, String username, String feed) {
this.id = id;
this.username = username;
this.feed = feed;
}
}

View File

@ -0,0 +1,19 @@
class TodoItem {
int id;
String task = "";
bool isCompleted = false;
TodoItem.fromElements(int id, String task, bool isCompleted) {
this.id = id;
this.task = task;
this.isCompleted = isCompleted;
}
Map toJson() {
Map jsonData = {
"__typename": "todos",
"id": id,
"title": task,
"is_completed": isCompleted,
};
return jsonData;
}
}

View File

@ -0,0 +1,63 @@
import 'package:app_boilerplate/screens/tabs/dashboard/feeds.dart';
import 'package:app_boilerplate/screens/tabs/dashboard/online.dart';
import 'package:app_boilerplate/screens/tabs/dashboard/todos.dart';
import 'package:app_boilerplate/services/shared_preferences_service.dart';
import 'package:flutter/material.dart';
class Dashboard extends StatelessWidget {
const Dashboard({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
title: Text(
"ToDo App",
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.exit_to_app),
onPressed: () async {
sharedPreferenceService.clearToken();
Navigator.pushReplacementNamed(context, "/login");
},
),
],
),
bottomNavigationBar: new TabBar(
tabs: [
Tab(
text: "Todos",
icon: new Icon(Icons.edit),
),
Tab(
text: "Feeds",
icon: new Icon(Icons.message),
),
Tab(
text: "Online",
icon: new Icon(Icons.people),
),
],
labelColor: Colors.black,
unselectedLabelColor: Colors.grey,
indicatorSize: TabBarIndicatorSize.label,
indicatorPadding: EdgeInsets.all(5.0),
indicatorColor: Colors.blue,
),
body: TabBarView(
physics: NeverScrollableScrollPhysics(),
children: [
Todos(),
Feeds(),
Online(),
],
),
),
);
}
}

Some files were not shown because too many files have changed in this diff Show More