Full Code of dannyconnell/qwitter for AI

main af8c2785caa7 cached
29 files
30.2 KB
8.7k tokens
5 symbols
1 requests
Download .txt
Repository: dannyconnell/qwitter
Branch: main
Commit: af8c2785caa7
Files: 29
Total size: 30.2 KB

Directory structure:
gitextract_860_bhxe/

├── .editorconfig
├── .gitignore
├── .postcssrc.js
├── LICENSE
├── README.md
├── babel.config.js
├── jsconfig.json
├── package.json
├── quasar.conf.js
├── src/
│   ├── App.vue
│   ├── boot/
│   │   ├── .gitkeep
│   │   └── firebase.js
│   ├── css/
│   │   ├── app.sass
│   │   └── quasar.variables.sass
│   ├── index.template.html
│   ├── layouts/
│   │   └── MainLayout.vue
│   ├── pages/
│   │   ├── Error404.vue
│   │   ├── PageAbout.vue
│   │   └── PageHome.vue
│   └── router/
│       ├── index.js
│       └── routes.js
├── src-cordova/
│   ├── .gitignore
│   ├── config.xml
│   ├── cordova-flag.d.ts
│   └── package.json
└── src-electron/
    ├── electron-flag.d.ts
    ├── icons/
    │   └── icon.icns
    └── main-process/
        ├── electron-main.dev.js
        └── electron-main.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true


================================================
FILE: .gitignore
================================================
.DS_Store
.thumbs.db
node_modules

# Quasar core related directories
.quasar
/dist

# Cordova related directories and files
/src-cordova/node_modules
/src-cordova/platforms
/src-cordova/plugins
/src-cordova/www

# Capacitor related directories and files
/src-capacitor/www
/src-capacitor/node_modules

# BEX related directories and files
/src-bex/www
/src-bex/js/core

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Editor directories and files
.idea
*.suo
*.ntvs*
*.njsproj
*.sln


================================================
FILE: .postcssrc.js
================================================
// https://github.com/michael-ciniawsky/postcss-load-config

module.exports = {
  plugins: [
    // to edit target browsers: use "browserslist" field in package.json
    require('autoprefixer')
  ]
}


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2021 Danny Connell

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# Qwitter (qwitter)

A Cross-Platrom Twitter Clone created with Quasar Framework, VueJS & Firebase

## Setup Firebase
- Create a new Firebase project named Qwitter
- Create a Web App named Qwitter
- Copy the config from the code sample that appears and add it to src/boot/firebase.js
- Create a Cloud Firestore database - make sure you choose "Start in test mode"

## Install the dependencies
```bash
npm install
```

## Web Version

### Start  in development mode
```bash
quasar dev
```

### Build for production
```bash
quasar build
```

## Desktop Version (Electron)

### Start  in development mode
```bash
quasar dev -m electron
```

### Build for production
To build for different platforms, change the `electron > packager > platform` setting in `quasar.conf.js` to `win32`, `darwin`, `mas` or `linux` 
```bash
quasar build -m electron
```

## iOS Version (Cordova)

### Install Cordova globally
```bash
npm install -g cordova
```
or
```bash
sudo npm install -g cordova
```

### Install Xcode

[Install Xcode](https://developer.apple.com/download/more/)

### Start  in development mode
```bash
quasar dev -m cordova -T ios
```

### Start on other Simulator Devices
```bash
cd src-cordova
cordova run ios --list
cd ..
quasar dev -m cordova -T ios -e "iPhone-12, 14.3"
```

### Build for production
```bash
quasar build -m cordova -T ios
```

## Android Version (Cordova)

### Install Cordova globally
```bash
npm install -g cordova
```
or
```bash
sudo npm install -g cordova
```

### Follow all steps on Quasar site

[Follow all steps on Quasar site](https://quasar.dev/quasar-cli/developing-cordova-apps/preparation#Android-setup)

### Launch Android Virtual Device
Android Studio > Configure > AVD Manager > Launch an AVD

### Start  in development mode
```bash
quasar dev -m cordova -T android
```

### Build for production
```bash
quasar build -m cordova -T android
```

================================================
FILE: babel.config.js
================================================

module.exports = {
  presets: [
    '@quasar/babel-preset-app'
  ]
}


================================================
FILE: jsconfig.json
================================================
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "src/*": [
        "src/*"
      ],
      "app/*": [
        "*"
      ],
      "components/*": [
        "src/components/*"
      ],
      "layouts/*": [
        "src/layouts/*"
      ],
      "pages/*": [
        "src/pages/*"
      ],
      "assets/*": [
        "src/assets/*"
      ],
      "boot/*": [
        "src/boot/*"
      ],
      "vue$": [
        "node_modules/vue/dist/vue.esm.js"
      ]
    }
  },
  "exclude": [
    "dist",
    ".quasar",
    "node_modules"
  ]
}

================================================
FILE: package.json
================================================
{
  "name": "qwitter",
  "version": "0.0.1",
  "description": "A Quasar Framework app",
  "productName": "Qwitter",
  "author": "Danny Connell",
  "private": true,
  "scripts": {
    "test": "echo \"No test specified\" && exit 0"
  },
  "dependencies": {
    "@quasar/extras": "^1.0.0",
    "core-js": "^3.6.5",
    "date-fns": "^2.16.1",
    "firebase": "^8.2.4",
    "quasar": "^1.0.0"
  },
  "devDependencies": {
    "@quasar/app": "^2.0.0",
    "devtron": "^1.4.0",
    "electron": "^9.4.1",
    "electron-debug": "^3.2.0",
    "electron-devtools-installer": "^3.1.1",
    "electron-packager": "^14.2.1"
  },
  "browserslist": [
    "last 10 Chrome versions",
    "last 10 Firefox versions",
    "last 4 Edge versions",
    "last 7 Safari versions",
    "last 8 Android versions",
    "last 8 ChromeAndroid versions",
    "last 8 FirefoxAndroid versions",
    "last 10 iOS versions",
    "last 5 Opera versions"
  ],
  "engines": {
    "node": ">= 10.18.1",
    "npm": ">= 6.13.4",
    "yarn": ">= 1.21.1"
  }
}


================================================
FILE: quasar.conf.js
================================================
/*
 * This file runs in a Node context (it's NOT transpiled by Babel), so use only
 * the ES6 features that are supported by your Node version. https://node.green/
 */

// Configuration for your app
// https://quasar.dev/quasar-cli/quasar-conf-js

module.exports = function (/* ctx */) {
  return {
    // https://quasar.dev/quasar-cli/supporting-ts
    supportTS: false,

    // https://quasar.dev/quasar-cli/prefetch-feature
    // preFetch: true,

    // app boot file (/src/boot)
    // --> boot files are part of "main.js"
    // https://quasar.dev/quasar-cli/boot-files
    boot: [
      'firebase'
    ],

    // https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css
    css: [
      'app.sass'
    ],

    // https://github.com/quasarframework/quasar/tree/dev/extras
    extras: [
      // 'ionicons-v4',
      // 'mdi-v5',
      'fontawesome-v5',
      // 'eva-icons',
      // 'themify',
      // 'line-awesome',
      // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!

      'roboto-font', // optional, you are not bound to it
      'material-icons', // optional, you are not bound to it
    ],

    // Full list of options: https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-build
    build: {
      vueRouterMode: 'hash', // available values: 'hash', 'history'

      // transpile: false,

      // Add dependencies for transpiling with Babel (Array of string/regex)
      // (from node_modules, which are by default not transpiled).
      // Applies only if "transpile" is set to true.
      // transpileDependencies: [],

      // rtl: false, // https://quasar.dev/options/rtl-support
      // preloadChunks: true,
      // showProgress: false,
      // gzip: true,
      // analyze: true,

      // Options below are automatically set depending on the env, set them if you want to override
      // extractCSS: false,

      // https://quasar.dev/quasar-cli/handling-webpack
      extendWebpack (cfg) {
      },
    },

    // Full list of options: https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-devServer
    devServer: {
      https: false,
      port: 8080,
      open: true // opens browser window automatically
    },

    // https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-framework
    framework: {
      iconSet: 'material-icons', // Quasar icon set
      lang: 'en-us', // Quasar language pack
      config: {},

      // Possible values for "importStrategy":
      // * 'auto' - (DEFAULT) Auto-import needed Quasar components & directives
      // * 'all'  - Manually specify what to import
      importStrategy: 'auto',

      // For special cases outside of where "auto" importStrategy can have an impact
      // (like functional components as one of the examples),
      // you can manually specify Quasar components/directives to be available everywhere:
      //
      // components: [],
      // directives: [],

      // Quasar plugins
      plugins: []
    },

    // animations: 'all', // --- includes all animations
    // https://quasar.dev/options/animations
    animations: ['fadeIn', 'fadeOut'],

    // https://quasar.dev/quasar-cli/developing-ssr/configuring-ssr
    ssr: {
      pwa: false
    },

    // https://quasar.dev/quasar-cli/developing-pwa/configuring-pwa
    pwa: {
      workboxPluginMode: 'GenerateSW', // 'GenerateSW' or 'InjectManifest'
      workboxOptions: {}, // only for GenerateSW
      manifest: {
        name: `Qwitter`,
        short_name: `Qwitter`,
        description: `A Quasar Framework app`,
        display: 'standalone',
        orientation: 'portrait',
        background_color: '#ffffff',
        theme_color: '#027be3',
        icons: [
          {
            src: 'icons/icon-128x128.png',
            sizes: '128x128',
            type: 'image/png'
          },
          {
            src: 'icons/icon-192x192.png',
            sizes: '192x192',
            type: 'image/png'
          },
          {
            src: 'icons/icon-256x256.png',
            sizes: '256x256',
            type: 'image/png'
          },
          {
            src: 'icons/icon-384x384.png',
            sizes: '384x384',
            type: 'image/png'
          },
          {
            src: 'icons/icon-512x512.png',
            sizes: '512x512',
            type: 'image/png'
          }
        ]
      }
    },

    // Full list of options: https://quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova
    cordova: {
      // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing
    },

    // Full list of options: https://quasar.dev/quasar-cli/developing-capacitor-apps/configuring-capacitor
    capacitor: {
      hideSplashscreen: true
    },

    // Full list of options: https://quasar.dev/quasar-cli/developing-electron-apps/configuring-electron
    electron: {
      bundler: 'packager', // 'packager' or 'builder'

      packager: {

        // platform: 'win32'

        // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options

        // OS X / Mac App Store
        // appBundleId: '',
        // appCategoryType: '',
        // osxSign: '',
        // protocol: 'myapp://path',

        // Windows only
        // win32metadata: { ... }
      },

      builder: {
        // https://www.electron.build/configuration/configuration

        appId: 'qwitter'
      },

      // More info: https://quasar.dev/quasar-cli/developing-electron-apps/node-integration
      nodeIntegration: true,

      extendWebpack (/* cfg */) {
        // do something with Electron main process Webpack cfg
        // chainWebpack also available besides this extendWebpack
      }
    }
  }
}


================================================
FILE: src/App.vue
================================================
<template>
  <div id="q-app">
    <router-view />
  </div>
</template>
<script>
export default {
  name: 'App'
}
</script>


================================================
FILE: src/boot/.gitkeep
================================================


================================================
FILE: src/boot/firebase.js
================================================
import firebase from "firebase/app"
import "firebase/firestore"

const firebaseConfig = {
  // YOUR CONFIG HERE
}

firebase.initializeApp(firebaseConfig)

let db = firebase.firestore()

export default db

================================================
FILE: src/css/app.sass
================================================
// app global css in Sass form


================================================
FILE: src/css/quasar.variables.sass
================================================
// Quasar Sass (& SCSS) Variables
// --------------------------------------------------
// To customize the look and feel of this app, you can override
// the Sass/SCSS variables found in Quasar's source Sass/SCSS files.

// Check documentation for full list of Quasar variables

// Your own variables (that are declared here) and Quasar's own
// ones will be available out of the box in your .vue/.scss/.sass files

// It's highly recommended to change the default colors
// to match your app's branding.
// Tip: Use the "Theme Builder" on Quasar's documentation website.

$primary   : #1da1f2
$secondary : #26A69A
$accent    : #9C27B0

$dark      : #1D1D1D

$positive  : #21BA45
$negative  : #C10015
$info      : #31CCEC
$warning   : #F2C037


================================================
FILE: src/index.template.html
================================================
<!DOCTYPE html>
<html>
  <head>
    <title><%= productName %></title>

    <meta charset="utf-8">
    <meta name="description" content="<%= productDescription %>">
    <meta name="format-detection" content="telephone=no">
    <meta name="msapplication-tap-highlight" content="no">
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>">

    <link rel="icon" type="image/png" sizes="128x128" href="icons/favicon-128x128.png">
    <link rel="icon" type="image/png" sizes="96x96" href="icons/favicon-96x96.png">
    <link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png">
    <link rel="icon" type="image/ico" href="favicon.ico">
  </head>
  <body>
    <!-- DO NOT touch the following DIV -->
    <div id="q-app"></div>
  </body>
</html>


================================================
FILE: src/layouts/MainLayout.vue
================================================
<template>
  <q-layout view="lHr lpR fFf">

    <q-header bordered class="bg-white text-black">
      <q-toolbar>
        <q-btn dense flat round icon="menu" @click="left = !left" />

        <q-toolbar-title class="text-weight-bold">
          <span class="gt-sm">{{ $route.name }}</span>
          <q-icon
            class="header-icon q-pa-md lt-md"
            name="fas fa-dove"
            size="sm"
            color="primary"
          />
        </q-toolbar-title>

      </q-toolbar>
    </q-header>

    <q-drawer
      v-model="left"
      side="left"
      :width="283"
      bordered
      show-if-above
    >
      <q-icon
        class="q-pa-md"
        name="fas fa-dove"
        size="lg"
        color="primary"
      />

      <q-list>
        <q-item
          to="/"
          v-ripple
          clickable
          exact
        >
          <q-item-section avatar>
            <q-icon name="home" size="md" />
          </q-item-section>

          <q-item-section class="text-h6 text-weight-bold">Home</q-item-section>
        </q-item>
        <q-item
          to="/about"
          v-ripple
          clickable
          exact
        >
          <q-item-section avatar>
            <q-icon name="help" size="md" />
          </q-item-section>

          <q-item-section class="text-h6 text-weight-bold">About</q-item-section>
        </q-item>
      </q-list>

    </q-drawer>

    <q-drawer show-if-above v-model="right" side="right" bordered>
      <q-input
        placeholder="Search Qwitter"
        class="q-ma-md"
        outlined
        rounded
        dense
      >
        <template v-slot:prepend>
          <q-icon name="search" />
        </template>
      </q-input>

      <q-list
        separator
        padding
      >
        <q-item class="q-pa-md">
          <q-item-section>
            <q-item-label overline class="text-grey">Education</q-item-label>
            <q-item-label class="text-weight-bold">Something amazing happened!</q-item-label>
            <q-item-label caption>Secondary line text. Lorem ipsum dolor sit amet, consectetur adipiscit elit.</q-item-label>
          </q-item-section>

          <q-item-section side top>
            <q-item-label caption>5 min ago</q-item-label>
          </q-item-section>
        </q-item>
        <q-item class="q-pa-md">
          <q-item-section>
            <q-item-label overline class="text-grey">Education</q-item-label>
            <q-item-label class="text-weight-bold">Something amazing happened!</q-item-label>
            <q-item-label caption>Secondary line text. Lorem ipsum dolor sit amet, consectetur adipiscit elit.</q-item-label>
          </q-item-section>

          <q-item-section side top>
            <q-item-label caption>5 min ago</q-item-label>
          </q-item-section>
        </q-item>
        <q-item class="q-pa-md">
          <q-item-section>
            <q-item-label overline class="text-grey">Education</q-item-label>
            <q-item-label class="text-weight-bold">Something amazing happened!</q-item-label>
            <q-item-label caption>Secondary line text. Lorem ipsum dolor sit amet, consectetur adipiscit elit.</q-item-label>
          </q-item-section>

          <q-item-section side top>
            <q-item-label caption>5 min ago</q-item-label>
          </q-item-section>
        </q-item>
      </q-list>
    </q-drawer>

    <q-page-container>
      <keep-alive>
        <router-view />
      </keep-alive>
    </q-page-container>

  </q-layout>
</template>

<script>
export default {
  data () {
    return {
      left: false,
      right: false
    }
  }
}
</script>

<style lang="sass">
.header-icon
  position: absolute
  bottom: 0
  left: 50%
  transform: translateX(-50%)
</style>

================================================
FILE: src/pages/Error404.vue
================================================
<template>
  <div class="fullscreen bg-blue text-white text-center q-pa-md flex flex-center">
    <div>
      <div style="font-size: 30vh">
        404
      </div>

      <div class="text-h2" style="opacity:.4">
        Oops. Nothing here...
      </div>

      <q-btn
        class="q-mt-xl"
        color="white"
        text-color="blue"
        unelevated
        to="/"
        label="Go Home"
        no-caps
      />
    </div>
  </div>
</template>

<script>
export default {
  name: 'Error404'
}
</script>


================================================
FILE: src/pages/PageAbout.vue
================================================
<template>
  <q-page class="q-pa-lg">
    <h4 class="q-mt-none q-mb-md text-weight-bold">About Qwitter</h4>
    <div class="text-body1">
      <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sunt similique molestias dolore, ab libero eius? Voluptatum quaerat architecto ex blanditiis, perspiciatis dolor quisquam labore fuga repellendus minima! Maxime, provident est.</p>
      <p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Sunt similique molestias dolore, ab libero eius? Voluptatum quaerat architecto ex blanditiis, perspiciatis dolor quisquam labore fuga repellendus minima! Maxime, provident est.</p>
    </div>
  </q-page>
</template>

<script>
export default {
  name: 'PageAbout'
}
</script>


================================================
FILE: src/pages/PageHome.vue
================================================
<template>
  <q-page class="relative-position">
    <q-scroll-area class="absolute full-width full-height">
      <div class="q-py-lg q-px-md row items-end q-col-gutter-md">
        <div class="col">
          <q-input
            v-model="newQweetContent"
            class="new-qweet"
            placeholder="What's happening?"
            maxlength="280"
            bottom-slots
            counter
            autogrow
          >
            <template v-slot:before>
              <q-avatar size="xl">
                <img src="https://s.gravatar.com/avatar/ce7f3697e231df38b3ca6065848520da?s=80">
              </q-avatar>
            </template>
          </q-input>
        </div>
        <div class="col col-shrink">
          <q-btn
            @click="addNewQweet"
            :disable="!newQweetContent"
            class="q-mb-lg"
            color="primary"
            label="Qweet"
            rounded
            unelevated
            no-caps
          />
        </div>
      </div>

      <q-separator
        class="divider"
        color="grey-2"
        size="10px"
      />

      <q-list separator>
        <transition-group
          appear
          enter-active-class="animated fadeIn slow"
          leave-active-class="animated fadeOut slow"
        >
          <q-item
            v-for="qweet in qweets"
            :key="qweet.id"
            class="qweet q-py-md"
          >
            <q-item-section avatar top>
              <q-avatar size="xl">
                <img src="https://s.gravatar.com/avatar/ce7f3697e231df38b3ca6065848520da?s=80">
              </q-avatar>
            </q-item-section>

            <q-item-section>
              <q-item-label class="text-subtitle1">
                <strong>Danny Connell</strong>
                <span class="text-grey-7">
                  @danny__connell 
                  <br class="lt-md">&bull; {{ qweet.date | relativeDate }}
                </span>
              </q-item-label>
              <q-item-label class="qweet-content text-body1">{{ qweet.content }}</q-item-label>
              <div class="qweet-icons row justify-between q-mt-sm">
                <q-btn
                  color="grey"
                  icon="far fa-comment"
                  size="sm"
                  flat
                  round
                />
                <q-btn
                  color="grey"
                  icon="fas fa-retweet"
                  size="sm"
                  flat
                  round
                />
                <q-btn
                  @click="toggleLiked(qweet)"
                  :color="qweet.liked ? 'pink' : 'grey'"
                  :icon="qweet.liked ? 'fas fa-heart' : 'far fa-heart'"
                  size="sm"
                  flat
                  round
                />
                <q-btn
                  @click="deleteQweet(qweet)"
                  color="grey"
                  icon="fas fa-trash"
                  size="sm"
                  flat
                  round
                />
              </div>
            </q-item-section>
          </q-item>
        </transition-group>
      </q-list>
    </q-scroll-area>
  </q-page>
</template>

<script>
import db from 'src/boot/firebase'
import { formatDistance } from 'date-fns'

export default {
  name: 'PageHome',
  data() {
    return {
      newQweetContent: '',
      qweets: [
        // {
        //   id: 'ID1',
        //   content: 'Be your own hero, its cheaper than a movie ticket.',
        //   date: 1611653238221,
        //   liked: false
        // },
        // {
        //   id: 'ID2',
        //   content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed feugiat justo id viverra consequat. Integer feugiat lorem faucibus est ornare scelerisque. Donec tempus, nunc vitae semper sagittis, odio magna semper ipsum, et laoreet sapien mauris vitae arcu.',
        //   date: 1611653252444,
        //   liked: true
        // },
      ]
    }
  },
  methods: {
    addNewQweet() {
      let newQweet = {
        content: this.newQweetContent,
        date: Date.now(),
        liked: false
      }
      // this.qweets.unshift(newQweet)
      db.collection('qweets').add(newQweet).then(function(docRef) {
        console.log('Document written with ID: ', docRef.id)
      }).catch(function(error) {
        console.error('Error adding document: ', error)
      })
      this.newQweetContent = ''
    },
    deleteQweet(qweet) {
      db.collection('qweets').doc(qweet.id).delete().then(function() {
        console.log('Document successfully deleted!');
      }).catch(function(error) {
        console.error('Error removing document: ', error);
      })
    },
    toggleLiked(qweet) {
      db.collection('qweets').doc(qweet.id).update({
        liked: !qweet.liked
      })
      .then(function() {
        console.log('Document successfully updated!')
      })
      .catch(function(error) {
        // The document probably doesn't exist.
        console.error('Error updating document: ', error)
      })
    }
  },
  filters: {
    relativeDate(value) {
      return formatDistance(value, new Date())
    }
  },
  mounted() {
    db.collection('qweets').orderBy('date').onSnapshot(snapshot => {
      snapshot.docChanges().forEach(change => {
        let qweetChange = change.doc.data()
        qweetChange.id = change.doc.id
        if (change.type === 'added') {
          console.log('New qweet: ', qweetChange)
          this.qweets.unshift(qweetChange)
        }
        if (change.type === 'modified') {
          console.log('Modified qweet: ', qweetChange)
          let index = this.qweets.findIndex(qweet => qweet.id === qweetChange.id)
          Object.assign(this.qweets[index], qweetChange)
        }
        if (change.type === 'removed') {
          console.log('Removed qweet: ', qweetChange)
          let index = this.qweets.findIndex(qweet => qweet.id === qweetChange.id)
          this.qweets.splice(index, 1)
        }
      })
    })
  }
}
</script>

<style lang="sass">
.new-qweet
  textarea
    font-size: 19px
    line-height: 1.4 !important
.divider
  border-top: 1px solid
  border-bottom: 1px solid
  border-color: $grey-4
.qweet:not(:first-child)
  border-top: 1px solid rgba(0, 0, 0, 0.12)
.qweet-content
  white-space: pre-line
.qweet-icons
  margin-left: -5px
</style>


================================================
FILE: src/router/index.js
================================================
import Vue from 'vue'
import VueRouter from 'vue-router'

import routes from './routes'

Vue.use(VueRouter)

/*
 * If not building with SSR mode, you can
 * directly export the Router instantiation;
 *
 * The function below can be async too; either use
 * async/await or return a Promise which resolves
 * with the Router instance.
 */

export default function (/* { store, ssrContext } */) {
  const Router = new VueRouter({
    scrollBehavior: () => ({ x: 0, y: 0 }),
    routes,

    // Leave these as they are and change in quasar.conf.js instead!
    // quasar.conf.js -> build -> vueRouterMode
    // quasar.conf.js -> build -> publicPath
    mode: process.env.VUE_ROUTER_MODE,
    base: process.env.VUE_ROUTER_BASE
  })

  return Router
}


================================================
FILE: src/router/routes.js
================================================

const routes = [
  {
    path: '/',
    component: () => import('layouts/MainLayout.vue'),
    children: [
      {
        path: '',
        component: () => import('pages/PageHome.vue'),
        name: 'Home'
      },
      { 
        path: '/about',
        component: () => import('pages/PageAbout.vue'),
        name: 'About'
      }
    ]
  },

  // Always leave this as last one,
  // but you can also remove it
  {
    path: '*',
    component: () => import('pages/Error404.vue')
  }
]

export default routes


================================================
FILE: src-cordova/.gitignore
================================================
.DS_Store

# Generated by package manager
node_modules/

# Generated by Cordova
/plugins/
/platforms/


================================================
FILE: src-cordova/config.xml
================================================
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.dannyconnell.qwitter" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>Qwitter</name>
    <description>A Quasar Framework app</description>
    <author email="dev@cordova.apache.org" href="http://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <platform name="android">
        <allow-intent href="market:*" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
        <preference name="ScrollEnabled" value="true" />
    </platform>
    <allow-navigation href="about:*" />
</widget>


================================================
FILE: src-cordova/cordova-flag.d.ts
================================================
// THIS FEATURE-FLAG FILE IS AUTOGENERATED,
//  REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING
import "quasar/dist/types/feature-flag";

declare module "quasar/dist/types/feature-flag" {
  interface QuasarFeatureFlags {
    cordova: true;
  }
}


================================================
FILE: src-cordova/package.json
================================================
{
  "name": "com.dannyconnell.qwitter",
  "displayName": "Qwitter",
  "version": "1.0.0",
  "description": "A sample Apache Cordova application that responds to the deviceready event.",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "ecosystem:cordova"
  ],
  "author": "Apache Cordova Team",
  "license": "Apache-2.0",
  "devDependencies": {
    "cordova-android": "^9.0.0",
    "cordova-ios": "^6.1.1",
    "cordova-plugin-ionic-webview": "^5.0.0",
    "cordova-plugin-whitelist": "^1.3.4"
  },
  "cordova": {
    "plugins": {
      "cordova-plugin-whitelist": {},
      "cordova-plugin-ionic-webview": {}
    },
    "platforms": [
      "ios",
      "android"
    ]
  }
}

================================================
FILE: src-electron/electron-flag.d.ts
================================================
// THIS FEATURE-FLAG FILE IS AUTOGENERATED,
//  REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING
import "quasar/dist/types/feature-flag";

declare module "quasar/dist/types/feature-flag" {
  interface QuasarFeatureFlags {
    electron: true;
  }
}


================================================
FILE: src-electron/main-process/electron-main.dev.js
================================================
/**
 * This file is used specifically and only for development. It installs
 * `electron-debug` & `vue-devtools`. There shouldn't be any need to
 *  modify this file, but it can be used to extend your development
 *  environment.
 */

import electronDebug from 'electron-debug'
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
import { app, BrowserWindow } from 'electron'

app.whenReady().then(() => {
  // allow for a small delay for mainWindow to be created
  setTimeout(() => {
    // Install `electron-debug` with `devtron`
    electronDebug({ showDevTools: false })

    // Install vuejs devtools
    installExtension(VUEJS_DEVTOOLS)
      .then(name => {
        console.log(`Added Extension: ${name}`)
        // get main window
        const win = BrowserWindow.getFocusedWindow()
        if (win) {
          win.webContents.on('did-frame-finish-load', () => {
            win.webContents.once('devtools-opened', () => {
              win.webContents.focus()
            })
            // open electron debug
            console.log('Opening dev tools')
            win.webContents.openDevTools()
          })
        }
      })
      .catch(err => {
        console.log('An error occurred: ', err)
      })
  }, 250)
})

import './electron-main'


================================================
FILE: src-electron/main-process/electron-main.js
================================================
import { app, BrowserWindow, nativeTheme } from 'electron'

try {
  if (process.platform === 'win32' && nativeTheme.shouldUseDarkColors === true) {
    require('fs').unlinkSync(require('path').join(app.getPath('userData'), 'DevTools Extensions'))
  }
} catch (_) { }

/**
 * Set `__statics` path to static files in production;
 * The reason we are setting it here is that the path needs to be evaluated at runtime
 */
if (process.env.PROD) {
  global.__statics = __dirname
}

let mainWindow

function createWindow () {
  /**
   * Initial window options
   */
  mainWindow = new BrowserWindow({
    width: 1024,
    minWidth: 1024,
    height: 600,
    useContentSize: true,
    webPreferences: {
      // Change from /quasar.conf.js > electron > nodeIntegration;
      // More info: https://quasar.dev/quasar-cli/developing-electron-apps/node-integration
      nodeIntegration: process.env.QUASAR_NODE_INTEGRATION,
      nodeIntegrationInWorker: process.env.QUASAR_NODE_INTEGRATION,

      // More info: /quasar-cli/developing-electron-apps/electron-preload-script
      // preload: path.resolve(__dirname, 'electron-preload.js')
    }
  })

  mainWindow.loadURL(process.env.APP_URL)

  mainWindow.on('closed', () => {
    mainWindow = null
  })
}

app.on('ready', createWindow)

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  if (mainWindow === null) {
    createWindow()
  }
})
Download .txt
gitextract_860_bhxe/

├── .editorconfig
├── .gitignore
├── .postcssrc.js
├── LICENSE
├── README.md
├── babel.config.js
├── jsconfig.json
├── package.json
├── quasar.conf.js
├── src/
│   ├── App.vue
│   ├── boot/
│   │   ├── .gitkeep
│   │   └── firebase.js
│   ├── css/
│   │   ├── app.sass
│   │   └── quasar.variables.sass
│   ├── index.template.html
│   ├── layouts/
│   │   └── MainLayout.vue
│   ├── pages/
│   │   ├── Error404.vue
│   │   ├── PageAbout.vue
│   │   └── PageHome.vue
│   └── router/
│       ├── index.js
│       └── routes.js
├── src-cordova/
│   ├── .gitignore
│   ├── config.xml
│   ├── cordova-flag.d.ts
│   └── package.json
└── src-electron/
    ├── electron-flag.d.ts
    ├── icons/
    │   └── icon.icns
    └── main-process/
        ├── electron-main.dev.js
        └── electron-main.js
Download .txt
SYMBOL INDEX (5 symbols across 4 files)

FILE: quasar.conf.js
  method extendWebpack (line 64) | extendWebpack (cfg) {
  method extendWebpack (line 187) | extendWebpack (/* cfg */) {

FILE: src-cordova/cordova-flag.d.ts
  type QuasarFeatureFlags (line 6) | interface QuasarFeatureFlags {

FILE: src-electron/electron-flag.d.ts
  type QuasarFeatureFlags (line 6) | interface QuasarFeatureFlags {

FILE: src-electron/main-process/electron-main.js
  function createWindow (line 19) | function createWindow () {
Condensed preview — 29 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (34K chars).
[
  {
    "path": ".editorconfig",
    "chars": 147,
    "preview": "root = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 2\nend_of_line = lf\ninsert_final_newline = true\ntrim_"
  },
  {
    "path": ".gitignore",
    "chars": 496,
    "preview": ".DS_Store\n.thumbs.db\nnode_modules\n\n# Quasar core related directories\n.quasar\n/dist\n\n# Cordova related directories and fi"
  },
  {
    "path": ".postcssrc.js",
    "chars": 200,
    "preview": "// https://github.com/michael-ciniawsky/postcss-load-config\n\nmodule.exports = {\n  plugins: [\n    // to edit target brows"
  },
  {
    "path": "LICENSE",
    "chars": 1070,
    "preview": "MIT License\n\nCopyright (c) 2021 Danny Connell\n\nPermission is hereby granted, free of charge, to any person obtaining a c"
  },
  {
    "path": "README.md",
    "chars": 1878,
    "preview": "# Qwitter (qwitter)\n\nA Cross-Platrom Twitter Clone created with Quasar Framework, VueJS & Firebase\n\n## Setup Firebase\n- "
  },
  {
    "path": "babel.config.js",
    "chars": 70,
    "preview": "\nmodule.exports = {\n  presets: [\n    '@quasar/babel-preset-app'\n  ]\n}\n"
  },
  {
    "path": "jsconfig.json",
    "chars": 548,
    "preview": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"paths\": {\n      \"src/*\": [\n        \"src/*\"\n      ],\n      \"app/*\": [\n "
  },
  {
    "path": "package.json",
    "chars": 1016,
    "preview": "{\n  \"name\": \"qwitter\",\n  \"version\": \"0.0.1\",\n  \"description\": \"A Quasar Framework app\",\n  \"productName\": \"Qwitter\",\n  \"a"
  },
  {
    "path": "quasar.conf.js",
    "chars": 5679,
    "preview": "/*\n * This file runs in a Node context (it's NOT transpiled by Babel), so use only\n * the ES6 features that are supporte"
  },
  {
    "path": "src/App.vue",
    "chars": 123,
    "preview": "<template>\n  <div id=\"q-app\">\n    <router-view />\n  </div>\n</template>\n<script>\nexport default {\n  name: 'App'\n}\n</scrip"
  },
  {
    "path": "src/boot/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/boot/firebase.js",
    "chars": 203,
    "preview": "import firebase from \"firebase/app\"\nimport \"firebase/firestore\"\n\nconst firebaseConfig = {\n  // YOUR CONFIG HERE\n}\n\nfireb"
  },
  {
    "path": "src/css/app.sass",
    "chars": 31,
    "preview": "// app global css in Sass form\n"
  },
  {
    "path": "src/css/quasar.variables.sass",
    "chars": 744,
    "preview": "// Quasar Sass (& SCSS) Variables\n// --------------------------------------------------\n// To customize the look and fee"
  },
  {
    "path": "src/index.template.html",
    "chars": 991,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <title><%= productName %></title>\n\n    <meta charset=\"utf-8\">\n    <meta name=\"descri"
  },
  {
    "path": "src/layouts/MainLayout.vue",
    "chars": 3751,
    "preview": "<template>\n  <q-layout view=\"lHr lpR fFf\">\n\n    <q-header bordered class=\"bg-white text-black\">\n      <q-toolbar>\n      "
  },
  {
    "path": "src/pages/Error404.vue",
    "chars": 515,
    "preview": "<template>\n  <div class=\"fullscreen bg-blue text-white text-center q-pa-md flex flex-center\">\n    <div>\n      <div style"
  },
  {
    "path": "src/pages/PageAbout.vue",
    "chars": 727,
    "preview": "<template>\n  <q-page class=\"q-pa-lg\">\n    <h4 class=\"q-mt-none q-mb-md text-weight-bold\">About Qwitter</h4>\n    <div cla"
  },
  {
    "path": "src/pages/PageHome.vue",
    "chars": 6348,
    "preview": "<template>\n  <q-page class=\"relative-position\">\n    <q-scroll-area class=\"absolute full-width full-height\">\n      <div c"
  },
  {
    "path": "src/router/index.js",
    "chars": 746,
    "preview": "import Vue from 'vue'\nimport VueRouter from 'vue-router'\n\nimport routes from './routes'\n\nVue.use(VueRouter)\n\n/*\n * If no"
  },
  {
    "path": "src/router/routes.js",
    "chars": 516,
    "preview": "\nconst routes = [\n  {\n    path: '/',\n    component: () => import('layouts/MainLayout.vue'),\n    children: [\n      {\n    "
  },
  {
    "path": "src-cordova/.gitignore",
    "chars": 102,
    "preview": ".DS_Store\n\n# Generated by package manager\nnode_modules/\n\n# Generated by Cordova\n/plugins/\n/platforms/\n"
  },
  {
    "path": "src-cordova/config.xml",
    "chars": 962,
    "preview": "<?xml version='1.0' encoding='utf-8'?>\n<widget id=\"com.dannyconnell.qwitter\" version=\"0.0.1\" xmlns=\"http://www.w3.org/ns"
  },
  {
    "path": "src-cordova/cordova-flag.d.ts",
    "chars": 258,
    "preview": "// THIS FEATURE-FLAG FILE IS AUTOGENERATED,\n//  REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING\nimport \"quas"
  },
  {
    "path": "src-cordova/package.json",
    "chars": 747,
    "preview": "{\n  \"name\": \"com.dannyconnell.qwitter\",\n  \"displayName\": \"Qwitter\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A sample Apa"
  },
  {
    "path": "src-electron/electron-flag.d.ts",
    "chars": 259,
    "preview": "// THIS FEATURE-FLAG FILE IS AUTOGENERATED,\n//  REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING\nimport \"quas"
  },
  {
    "path": "src-electron/main-process/electron-main.dev.js",
    "chars": 1287,
    "preview": "/**\n * This file is used specifically and only for development. It installs\n * `electron-debug` & `vue-devtools`. There "
  },
  {
    "path": "src-electron/main-process/electron-main.js",
    "chars": 1460,
    "preview": "import { app, BrowserWindow, nativeTheme } from 'electron'\n\ntry {\n  if (process.platform === 'win32' && nativeTheme.shou"
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the dannyconnell/qwitter GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 29 files (30.2 KB), approximately 8.7k tokens, and a symbol index with 5 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!