Hidden Drawer Menu in flutter

Hidden Drawer Menu

Hidden Drawer Menu is a library for adding a beautiful drawer mode menu feature with perspective animation.

You can use a pre-defined menu or make a fully customized menu.

Usage of the hidden_drawer_menu widget on an android device

Download APK Example

Use with default menu


import 'package:hidden_drawer_menu/model/hidden_drawer_menu.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<ScreenHiddenDrawer> itens = new List();

  @override
  void initState() {
    itens.add(new ScreenHiddenDrawer(
        new ItemHiddenMenu(
          name: "Screen 1",
          baseStyle: TextStyle( color: Colors.white.withOpacity(0.8), fontSize: 28.0 ),
          colorLineSelected: Colors.teal,
        ),
        FirstSreen()));

    itens.add(new ScreenHiddenDrawer(
        new ItemHiddenMenu(
          name: "Screen 2",
          baseStyle: TextStyle( color: Colors.white.withOpacity(0.8), fontSize: 28.0 ),
          colorLineSelected: Colors.orange,
        ),
        SecondSreen()));

    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    return HiddenDrawerMenu(
      backgroundColorMenu: Colors.blueGrey,
      backgroundColorAppBar: Colors.cyan,
      screens: itens,
        //    typeOpen: TypeOpen.FROM_RIGHT,
        //    disableAppBarDefault: false,
        //    enableScaleAnimin: true,
        //    enableCornerAnimin: true,
        //    slidePercent: 80.0,
        //    verticalScalePercent: 80.0,
        //    contentCornerRadius: 10.0,
        //    iconMenuAppBar: Icon(Icons.menu),
        //    backgroundContent: DecorationImage((image: ExactAssetImage('assets/bg_news.jpg'),fit: BoxFit.cover),
        //    whithAutoTittleName: true,
        //    styleAutoTittleName: TextStyle(color: Colors.red),
        //    actionsAppBar: <Widget>[],
        //    backgroundColorContent: Colors.blue,
        //    elevationAppBar: 4.0,
        //    tittleAppBar: Center(child: Icon(Icons.ac_unit),),
        //    enableShadowItensMenu: true,
        //    backgroundMenu: DecorationImage(image: ExactAssetImage('assets/bg_news.jpg'),fit: BoxFit.cover),
    );
    
  }
}

Use with full customization menu


import 'package:hidden_drawer_menu/model/hidden_drawer_menu.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SimpleHiddenDrawer(
        menu: Menu(),
        screenSelectedBuilder: (position,controller) {
          
          Widget screenCurrent;
          
          switch(position){
            case 0 : screenCurrent = Screen1(); break;
            case 1 : screenCurrent = Screen2(); break;
            case 2 : screenCurrent = Screen3(); break;
          }
          
          return Scaffold(
            backgroundColor: backgroundColorContent,
            appBar: AppBar(
              leading: IconButton(
                  icon: Icon(Icons.menu),
                  onPressed: () {
                    controller.toggle();
                  }),
            ),
            body: screenCurrent,
          );
          
        },
      ),
    );
  }
}

class Menu extends StatefulWidget {
  @override
  _SecondSreenState createState() => _MenuState();
}

class _MenuState extends State<SecondSreen> {

  SimpleHiddenDrawerController controller;

  @override
  void didChangeDependencies() {
    controller = SimpleHiddenDrawerController.of(context);
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: double.maxFinite,
      height: double.maxFinite,
      color: Colors.cyan,
      padding: const EdgeInsets.all(8.0),
      child: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            RaisedButton(
              onPressed: () {
                controller.setSelectedMenuPosition(0);
              },
              child: Text("Menu 1"),
            ),
            RaisedButton(
              onPressed: () {
                controller.setSelectedMenuPosition(1);
              },
              child: Text("Menu 2"),
            )
          ],
        ),
      ),
    );
  }
}

Actions

This actions is only accessible by the children of HiddenDrawerMenu or SimpleHiddenDrawer.

Select item menu

SimpleHiddenDrawerController.of(context).setSelectedMenuPosition(0);

Toggle menu (if opened will close, if closed will open)

SimpleHiddenDrawerController.of(context).toggle();

Open

SimpleHiddenDrawerController.of(context).open();

Close

SimpleHiddenDrawerController.of(context).close();

Listen selected position

final controller = SimpleHiddenDrawerController.of(context);
controller.addListener((){
  print(controller.position);
});

Listen to menu status (closed,opening,open,closing)

final controller = SimpleHiddenDrawerController.of(context);
controller.addListener((){
  print(controller.state);
});

If you want to use only the widget responsible for the animation, it is now available as AnimatedDrawerContent

Example usage AnimatedDrawerContent

AnimatedDrawerController controller = AnimatedDrawerController(
  vsync: this,
  animationCurve:Curves.decelerate,
  duration:const Duration(milliseconds: 350,
);

return AnimatedDrawerContent(
  controller: controller,
  whithPaddingTop: false, //(optional) default = false // Add padding top in de gesture equals Heigth of the AppBar
  whithShadow: false, //(optional) default = false
  isDraggable: true, //(optional) default = true
  child: Screen(),
);

You can control actions by controller such as:

controller.toggle() // Open or Close
controller.open()
controller.close()
controller.move(percent) // moves to a specific position from 0 to 1 (0 = fully enclosed, 1 = fully opened)

Available settings

Menu

  • change BackgroundColor
  • set DecorationImage backgroud
  • enable Shadow above itens

Itens Menu

  • change colorText when selected
  • change colorText when unselected
  • change color lineleft selected

AppBar

  • change menu icon
  • change elavation
  • change BackgroundColor
  • set AutoTittleName
  • set actions
  • set widget in tittleAppBar

Content

  • change BackgroundColor
  • enable dragable
  • change curve animation

Use this package as a library

Depend on it

Run this command:

With Flutter:

 $ flutter pub add hidden_drawer_menu

This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get):

dependencies:
  hidden_drawer_menu: ^3.0.1

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:hidden_drawer_menu/hidden_drawer_menu.dart'; 

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:hidden_drawer_menu_demo/custom/example_custom_menu.dart';
import 'package:hidden_drawer_menu_demo/simple/example_hidden_drawer.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            SizedBox(
              width: 200.0,
              child: ElevatedButton(
                style: ButtonStyle(
                  backgroundColor: MaterialStateProperty.all(Colors.blue),
                  shape: MaterialStateProperty.all(
                    RoundedRectangleBorder(
                      borderRadius: BorderRadius.all(
                        Radius.circular(
                          20.0,
                        ),
                      ),
                    ),
                  ),
                ),
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => ExampleHiddenDrawer(),
                    ),
                  );
                },
                child: Text(
                  "Default Example",
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ),
            SizedBox(
              width: 200.0,
              child: ElevatedButton(
                style: ButtonStyle(
                  backgroundColor: MaterialStateProperty.all(Colors.orange),
                  shape: MaterialStateProperty.all(
                    RoundedRectangleBorder(
                      borderRadius: BorderRadius.all(
                        Radius.circular(
                          20.0,
                        ),
                      ),
                    ),
                  ),
                ),
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (context) => ExampleCustomMenu()),
                  );
                },
                child: Text(
                  "Custom Menu Drawer",
                  style: TextStyle(color: Colors.white),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
} 

Download Details:

Author: RafaelBarbosatec

Source Code: https://github.com/RafaelBarbosatec/hidden_drawer_menu

#flutter #drawer #menu 

Hidden Drawer Menu  in flutter
Nat  Grady

Nat Grady

1658920920

Electron-input-menu: Context Menu for Electron input Elements

electron-input-menu

Context menu for electron input elements.

Installation

npm install --save electron-input-menu

Usage

This module expose a middleware for electron-contextmenu-middleware.

To use input context menu, you have to require this module and electron-contextmenu-middleware in renderer process and then mount this module as a middleware.

  const inputMenu = require('electron-input-menu');
  const context = require('electron-contextmenu-middleware');

  context.use(inputMenu);

  context.activate();

Keyboard shortcuts

electron-input-menu can also register shortcuts on DOM document object to handle copy, paste, cut, selectAll, undo and redo action. This is useful if your app doesn't provide an "Edit" menu that can handle this shortcuts.

To activate the shortcuts, call the registerShortcuts method in renderer process.

  const inputMenu = require('electron-input-menu');
  inputMenu.registerShortcuts();

Related projects

electron-contextmenu-middleware - Build electron context menus composing multiple middlewares functions.

debug-menu - Chrome-like "inspect element" context-menu.

Author: Parro-it
Source Code: https://github.com/parro-it/electron-input-menu 
License: MIT license

#electron #input #menu #context 

Electron-input-menu: Context Menu for Electron input Elements
Nat  Grady

Nat Grady

1658849460

Electron-create-menu: A Default Menu for Your Electron Applications

Electron-create-menu   

Provides a default menu for your electron applications, with convenience functions for multiplatform use and i18n.

Installation

Install using npm install electron-create-menu.

Usage

Instead of importing Menu from electron, import it from electron-create-menu:

import Menu from "electron-create-menu";
// or
const Menu = require("electron-create-menu");

To get a default menu with platform-appropriate menu items and submenus, call Menu like so:

Menu();

Note: This API has to be called after the ready event of app module.

Menu always returns the menu object that Menu.buildFromTemplate creates, so you can access instance methods on it.

Optional arguments

Menu has two optional functions you can pass it

  • The first argument is the callback function, where you can further edit (or replace) the generated menu.
  • The second argument is the i18n function where you can supply a function to use for translating the menu items.
Menu(callback, i18n);

The callback function

callback receives two arguments:

  • The generated menu
  • A function that returns {type: 'separator'} for convenience.

It expects you to return a menu-like object, either the edited default menu or a new menu.

Callback example

To append a menu item to the menu, push an object onto menu and return it:

Menu((defaultMenu, separator) => {
  defaultMenu.push({
    label: "My custom menu!",
    submenu: [
      { label: "my first item" },
      separator(),
      { label: "my second item" }
    ]
  });

  return defaultMenu;
});

The i18n function

The i18n function is applied to the labels of the default menu. There are two things worth mentioning:

  • Most items in the default menu are specified by a role, so the OS will supply the translation.
  • Labels added in the callback function are not translated by this function.

Example using i18next

const i18next = require('i18next');

i18next.init({
  /* assumed setup of i18next here */
}).then(function(t) {

  Menu(
    menu => {
      menu.push({
        label: i18next.t('My custom menu!'),
        submenu: [
          {label: i18next.t('my first item')},
          {label: i18next.t('my second item')},
        ],
      }),

      return menu;
    },

    // This function is used to translate the default labels
    i18next.t
  );

});

Multiplatform use

Each item in your menu can have two new properties, showOn and hideOn. These accept a string or an array of strings that correspond to process.platform values such as 'darwin' or 'win32'.

// this shows the menu item only on macOs
{
  showOn: "darwin";
}

// this hides the menu item on windows and macOs
{
  hideOn: ["win32", "darwin"];
}

With these, you can adapt your menu to multiple platforms without having to maintain multiple menu templates. See the default template for an example of a consolidated template.

You can also add a string or an array of strings as an argument to the separator function: separator('darwin'). The given value is interpreted as the value for showOn.

Example

Menu((defaultMenu, separator) => {

  defaultMenu.push({
    label: "My custom menu!",
    submenu: [
      {
        label: 'This is only shown on macOs',
        showOn: 'darwin',
      },
      separator('darwin'), // this is shown only macOs
      {label:
        'This is hidden on windows'
        hideOn: ['win32']
      },
    ],
  });

  return defaultMenu;
});

Made by @kilianvalkhof

Other projects:

  • 💻 Polypane - Develop responsive websites and apps twice as fast on multiple screens at once
  • 🖌️ Superposition - Kickstart your design system by extracting design tokens from your website
  • 🗒️ FromScratch - A smart but simple autosaving scratchpad

Author: Kilian
Source Code: https://github.com/kilian/electron-create-menu 
License: ISC license

#electron #menu #javascript #i18n #node 

Electron-create-menu: A Default Menu for Your Electron Applications
Rupert  Beatty

Rupert Beatty

1658755800

Laravel-nestedset: Effective Tree Structures in Laravel 4-8

This is a Laravel 4-8 package for working with trees in relational databases.

  • Laravel 5.7, 5.8, 6.0, 7.0, 8.0 is supported since v5
  • Laravel 5.5, 5.6 is supported since v4.3
  • Laravel 5.2, 5.3, 5.4 is supported since v4
  • Laravel 5.1 is supported in v3
  • Laravel 4 is supported in v2

What are nested sets?

Nested sets or Nested Set Model is a way to effectively store hierarchical data in a relational table. From wikipedia:

The nested set model is to number the nodes according to a tree traversal, which visits each node twice, assigning numbers in the order of visiting, and at both visits. This leaves two numbers for each node, which are stored as two attributes. Querying becomes inexpensive: hierarchy membership can be tested by comparing these numbers. Updating requires renumbering and is therefore expensive.

Applications

NSM shows good performance when tree is updated rarely. It is tuned to be fast for getting related nodes. It'is ideally suited for building multi-depth menu or categories for shop.

Documentation

Suppose that we have a model Category; a $node variable is an instance of that model and the node that we are manipulating. It can be a fresh model or one from database.

Relationships

Node has following relationships that are fully functional and can be eagerly loaded:

  • Node belongs to parent
  • Node has many children
  • Node has many ancestors
  • Node has many descendants

Inserting nodes

Moving and inserting nodes includes several database queries, so it is highly recommended to use transactions.

IMPORTANT! As of v4.2.0 transaction is not automatically started

Another important note is that structural manipulations are deferred until you hit save on model (some methods implicitly call save and return boolean result of the operation).

If model is successfully saved it doesn't mean that node was moved. If your application depends on whether the node has actually changed its position, use hasMoved method:

if ($node->save()) {
    $moved = $node->hasMoved();
}

Creating nodes

When you simply creating a node, it will be appended to the end of the tree:

Category::create($attributes); // Saved as root
$node = new Category($attributes);
$node->save(); // Saved as root

In this case the node is considered a root which means that it doesn't have a parent.

Making a root from existing node

// #1 Implicit save
$node->saveAsRoot();

// #2 Explicit save
$node->makeRoot()->save();

The node will be appended to the end of the tree.

Appending and prepending to the specified parent

If you want to make node a child of other node, you can make it last or first child.

In following examples, $parent is some existing node.

There are few ways to append a node:

// #1 Using deferred insert
$node->appendToNode($parent)->save();

// #2 Using parent node
$parent->appendNode($node);

// #3 Using parent's children relationship
$parent->children()->create($attributes);

// #5 Using node's parent relationship
$node->parent()->associate($parent)->save();

// #6 Using the parent attribute
$node->parent_id = $parent->id;
$node->save();

// #7 Using static method
Category::create($attributes, $parent);

And only a couple ways to prepend:

// #1
$node->prependToNode($parent)->save();

// #2
$parent->prependNode($node);

Inserting before or after specified node

You can make $node to be a neighbor of the $neighbor node using following methods:

$neighbor must exists, target node can be fresh. If target node exists, it will be moved to the new position and parent will be changed if it's required.

# Explicit save
$node->afterNode($neighbor)->save();
$node->beforeNode($neighbor)->save();

# Implicit save
$node->insertAfterNode($neighbor);
$node->insertBeforeNode($neighbor);

Building a tree from array

When using static method create on node, it checks whether attributes contains children key. If it does, it creates more nodes recursively.

$node = Category::create([
    'name' => 'Foo',

    'children' => [
        [
            'name' => 'Bar',

            'children' => [
                [ 'name' => 'Baz' ],
            ],
        ],
    ],
]);

$node->children now contains a list of created child nodes.

Rebuilding a tree from array

You can easily rebuild a tree. This is useful for mass-changing the structure of the tree.

Category::rebuildTree($data, $delete);

$data is an array of nodes:

$data = [
    [ 'id' => 1, 'name' => 'foo', 'children' => [ ... ] ],
    [ 'name' => 'bar' ],
];

There is an id specified for node with the name of foo which means that existing node will be filled and saved. If node is not exists ModelNotFoundException is thrown. Also, this node has children specified which is also an array of nodes; they will be processed in the same manner and saved as children of node foo.

Node bar has no primary key specified, so it will be created.

$delete shows whether to delete nodes that are already exists but not present in $data. By default, nodes aren't deleted.

Rebuilding a subtree

As of 4.2.8 you can rebuild a subtree:

Category::rebuildSubtree($root, $data);

This constraints tree rebuilding to descendants of $root node.

Retrieving nodes

In some cases we will use an $id variable which is an id of the target node.

Ancestors and descendants

Ancestors make a chain of parents to the node. Helpful for displaying breadcrumbs to the current category.

Descendants are all nodes in a sub tree, i.e. children of node, children of children, etc.

Both ancestors and descendants can be eagerly loaded.

// Accessing ancestors
$node->ancestors;

// Accessing descendants
$node->descendants;

It is possible to load ancestors and descendants using custom query:

$result = Category::ancestorsOf($id);
$result = Category::ancestorsAndSelf($id);
$result = Category::descendantsOf($id);
$result = Category::descendantsAndSelf($id);

In most cases, you need your ancestors to be ordered by the level:

$result = Category::defaultOrder()->ancestorsOf($id);

A collection of ancestors can be eagerly loaded:

$categories = Category::with('ancestors')->paginate(30);

// in view for breadcrumbs:
@foreach($categories as $i => $category)
    <small>{{ $category->ancestors->count() ? implode(' > ', $category->ancestors->pluck('name')->toArray()) : 'Top Level' }}</small><br>
    {{ $category->name }}
@endforeach

Siblings

Siblings are nodes that have same parent.

$result = $node->getSiblings();

$result = $node->siblings()->get();

To get only next siblings:

// Get a sibling that is immediately after the node
$result = $node->getNextSibling();

// Get all siblings that are after the node
$result = $node->getNextSiblings();

// Get all siblings using a query
$result = $node->nextSiblings()->get();

To get previous siblings:

// Get a sibling that is immediately before the node
$result = $node->getPrevSibling();

// Get all siblings that are before the node
$result = $node->getPrevSiblings();

// Get all siblings using a query
$result = $node->prevSiblings()->get();

Getting related models from other table

Imagine that each category has many goods. I.e. HasMany relationship is established. How can you get all goods of $category and every its descendant? Easy!

// Get ids of descendants
$categories = $category->descendants()->pluck('id');

// Include the id of category itself
$categories[] = $category->getKey();

// Get goods
$goods = Goods::whereIn('category_id', $categories)->get();

Including node depth

If you need to know at which level the node is:

$result = Category::withDepth()->find($id);

$depth = $result->depth;

Root node will be at level 0. Children of root nodes will have a level of 1, etc.

To get nodes of specified level, you can apply having constraint:

$result = Category::withDepth()->having('depth', '=', 1)->get();

IMPORTANT! This will not work in database strict mode

Default order

All nodes are strictly organized internally. By default, no order is applied, so nodes may appear in random order and this doesn't affect displaying a tree. You can order nodes by alphabet or other index.

But in some cases hierarchical order is essential. It is required for retrieving ancestors and can be used to order menu items.

To apply tree order defaultOrder method is used:

$result = Category::defaultOrder()->get();

You can get nodes in reversed order:

$result = Category::reversed()->get();

To shift node up or down inside parent to affect default order:

$bool = $node->down();
$bool = $node->up();

// Shift node by 3 siblings
$bool = $node->down(3);

The result of the operation is boolean value of whether the node has changed its position.

Constraints

Various constraints that can be applied to the query builder:

  • whereIsRoot() to get only root nodes;
  • hasParent() to get non-root nodes;
  • whereIsLeaf() to get only leaves;
  • hasChildren() to get non-leave nodes;
  • whereIsAfter($id) to get every node (not just siblings) that are after a node with specified id;
  • whereIsBefore($id) to get every node that is before a node with specified id.

Descendants constraints:

$result = Category::whereDescendantOf($node)->get();
$result = Category::whereNotDescendantOf($node)->get();
$result = Category::orWhereDescendantOf($node)->get();
$result = Category::orWhereNotDescendantOf($node)->get();
$result = Category::whereDescendantAndSelf($id)->get();

// Include target node into result set
$result = Category::whereDescendantOrSelf($node)->get();

Ancestor constraints:

$result = Category::whereAncestorOf($node)->get();
$result = Category::whereAncestorOrSelf($id)->get();

$node can be either a primary key of the model or model instance.

Building a tree

After getting a set of nodes, you can convert it to tree. For example:

$tree = Category::get()->toTree();

This will fill parent and children relationships on every node in the set and you can render a tree using recursive algorithm:

$nodes = Category::get()->toTree();

$traverse = function ($categories, $prefix = '-') use (&$traverse) {
    foreach ($categories as $category) {
        echo PHP_EOL.$prefix.' '.$category->name;

        $traverse($category->children, $prefix.'-');
    }
};

$traverse($nodes);

This will output something like this:

- Root
-- Child 1
--- Sub child 1
-- Child 2
- Another root

Building flat tree

Also, you can build a flat tree: a list of nodes where child nodes are immediately after parent node. This is helpful when you get nodes with custom order (i.e. alphabetically) and don't want to use recursion to iterate over your nodes.

$nodes = Category::get()->toFlatTree();

Previous example will output:

Root
Child 1
Sub child 1
Child 2
Another root

Getting a subtree

Sometimes you don't need whole tree to be loaded and just some subtree of specific node. It is show in following example:

$root = Category::descendantsAndSelf($rootId)->toTree()->first();

In a single query we are getting a root of a subtree and all of its descendants that are accessible via children relation.

If you don't need $root node itself, do following instead:

$tree = Category::descendantsOf($rootId)->toTree($rootId);

Deleting nodes

To delete a node:

$node->delete();

IMPORTANT! Any descendant that node has will also be deleted!

IMPORTANT! Nodes are required to be deleted as models, don't try do delete them using a query like so:

Category::where('id', '=', $id)->delete();

This will break the tree!

SoftDeletes trait is supported, also on model level.

Helper methods

To check if node is a descendant of other node:

$bool = $node->isDescendantOf($parent);

To check whether the node is a root:

$bool = $node->isRoot();

Other checks:

  • $node->isChildOf($other);
  • $node->isAncestorOf($other);
  • $node->isSiblingOf($other);
  • $node->isLeaf()

Checking consistency

You can check whether a tree is broken (i.e. has some structural errors):

$bool = Category::isBroken();

It is possible to get error statistics:

$data = Category::countErrors();

It will return an array with following keys:

  • oddness -- the number of nodes that have wrong set of lft and rgt values
  • duplicates -- the number of nodes that have same lft or rgt values
  • wrong_parent -- the number of nodes that have invalid parent_id value that doesn't correspond to lft and rgt values
  • missing_parent -- the number of nodes that have parent_id pointing to node that doesn't exists

Fixing tree

Since v3.1 tree can now be fixed. Using inheritance info from parent_id column, proper _lft and _rgt values are set for every node.

Node::fixTree();

Scoping

Imagine you have Menu model and MenuItems. There is a one-to-many relationship set up between these models. MenuItem has menu_id attribute for joining models together. MenuItem incorporates nested sets. It is obvious that you would want to process each tree separately based on menu_id attribute. In order to do so, you need to specify this attribute as scope attribute:

protected function getScopeAttributes()
{
    return [ 'menu_id' ];
}

But now, in order to execute some custom query, you need to provide attributes that are used for scoping:

MenuItem::scoped([ 'menu_id' => 5 ])->withDepth()->get(); // OK
MenuItem::descendantsOf($id)->get(); // WRONG: returns nodes from other scope
MenuItem::scoped([ 'menu_id' => 5 ])->fixTree(); // OK

When requesting nodes using model instance, scopes applied automatically based on the attributes of that model:

$node = MenuItem::findOrFail($id);

$node->siblings()->withDepth()->get(); // OK

To get scoped query builder using instance:

$node->newScopedQuery();

Scoping and eager loading

Always use scoped query when eager loading:

MenuItem::scoped([ 'menu_id' => 5])->with('descendants')->findOrFail($id); // OK
MenuItem::with('descendants')->findOrFail($id); // WRONG

Requirements

  • PHP >= 5.4
  • Laravel >= 4.1

It is highly suggested to use database that supports transactions (like MySql's InnoDb) to secure a tree from possible corruption.

Installation

To install the package, in terminal:

composer require kalnoy/nestedset

Setting up from scratch

The schema

For Laravel 5.5 and above users:

Schema::create('table', function (Blueprint $table) {
    ...
    $table->nestedSet();
});

// To drop columns
Schema::table('table', function (Blueprint $table) {
    $table->dropNestedSet();
});

For prior Laravel versions:

...
use Kalnoy\Nestedset\NestedSet;

Schema::create('table', function (Blueprint $table) {
    ...
    NestedSet::columns($table);
});

To drop columns:

...
use Kalnoy\Nestedset\NestedSet;

Schema::table('table', function (Blueprint $table) {
    NestedSet::dropColumns($table);
});

The model

Your model should use Kalnoy\Nestedset\NodeTrait trait to enable nested sets:

use Kalnoy\Nestedset\NodeTrait;

class Foo extends Model {
    use NodeTrait;
}

Migrating existing data

Migrating from other nested set extension

If your previous extension used different set of columns, you just need to override following methods on your model class:

public function getLftName()
{
    return 'left';
}

public function getRgtName()
{
    return 'right';
}

public function getParentIdName()
{
    return 'parent';
}

// Specify parent id attribute mutator
public function setParentAttribute($value)
{
    $this->setParentIdAttribute($value);
}

Migrating from basic parentage info

If your tree contains parent_id info, you need to add two columns to your schema:

$table->unsignedInteger('_lft');
$table->unsignedInteger('_rgt');

After setting up your model you only need to fix the tree to fill _lft and _rgt columns:

MyModel::fixTree();

Although this project is completely free for use, I appreciate any support!

Author: lazychaser
Source Code: https://github.com/lazychaser/laravel-nestedset 
License: 

#laravel #php #menu 

Laravel-nestedset: Effective Tree Structures in Laravel 4-8
Nat  Grady

Nat Grady

1658599020

Electron-context-menu: Context Menu for Your Electron App

electron-context-menu

Context menu for your Electron app

Electron doesn't have a built-in context menu. You're supposed to handle that yourself. But it's both tedious and hard to get right. This module gives you a nice extensible context menu with spellchecking and items like Cut/Copy/Paste for text, Save Image for images, and Copy Link for links. It also adds an Inspect Element menu item when in development to quickly view items in the inspector like in Chrome.

This package can only be used in the main process.

Install

$ npm install electron-context-menu

Requires Electron 10 or later.

Usage

const {app, BrowserWindow} = require('electron');
const contextMenu = require('electron-context-menu');

contextMenu({
	showSaveImageAs: true
});

let mainWindow;
(async () => {
	await app.whenReady();

	mainWindow = new BrowserWindow({
		webPreferences: {
			spellcheck: true
		}
	});
})();

Advanced example:

const {app, BrowserWindow} = require('electron');
const contextMenu = require('electron-context-menu');

contextMenu({
	prepend: (defaultActions, parameters, browserWindow) => [
		{
			label: 'Rainbow',
			// Only show it when right-clicking images
			visible: parameters.mediaType === 'image'
		},
		{
			label: 'Search Google for “{selection}”',
			// Only show it when right-clicking text
			visible: parameters.selectionText.trim().length > 0,
			click: () => {
				shell.openExternal(`https://google.com/search?q=${encodeURIComponent(parameters.selectionText)}`);
			}
		}
	]
});

let mainWindow;
(async () => {
	await app.whenReady();

	mainWindow = new BrowserWindow({
		webPreferences: {
			spellcheck: true
		}
	});
})();

The return value of contextMenu() is a function that disposes of the created event listeners:

const dispose = contextMenu(); dispose();

API

contextMenu(options?)

Creates a context menu and returns a dispose function.

options

Type: object

window

Type: BrowserWindow | BrowserView | WebViewTag | WebContents

Window or WebView to add the context menu to.

When not specified, the context menu will be added to all existing and new windows.

prepend

Type: Function

Should return an array of MenuItem's to be prepended to the context menu.

The first argument is an array of default actions that can be used. The second argument is this parameters object. The third argument is the BrowserWindow the context menu was requested for. The fourth argument is the context menu event.

MenuItem labels may contain the placeholder {selection} which will be replaced by the currently selected text as described in options.labels.

append

Type: Function

Should return an array of MenuItem's to be appended to the context menu.

The first argument is an array of default actions that can be used. The second argument is this parameters object. The third argument is the BrowserWindow the context menu was requested for. The fourth argument is the context menu event.

MenuItem labels may contain the placeholder {selection} which will be replaced by the currently selected text as described in options.labels.

showLearnSpelling

Type: boolean
Default: true

Show the Learn Spelling {selection} menu item when right-clicking text.

Even if true, the spellcheck preference in browser window must still be enabled. It will also only show when right-clicking misspelled words.

showLookUpSelection

Type: boolean
Default: true

Show the Look Up {selection} menu item when right-clicking text.

showSearchWithGoogle

Type: boolean
Default: true

Show the Search with Google menu item when right-clicking text.

showCopyImage

Type: boolean
Default: true

Show the Copy Image menu item when right-clicking on an image.

showCopyImageAddress

Type: boolean
Default: false

Show the Copy Image Address menu item when right-clicking on an image.

showSaveImage

Type: boolean
Default: false

Show the Save Image menu item when right-clicking on an image.

showSaveImageAs

Type: boolean
Default: false

Show the Save Image As… menu item when right-clicking on an image.

showSaveLinkAs

Type: boolean
Default: false

Show the Save Link As… menu item when right-clicking on a link.

showInspectElement

Type: boolean
Default: Only in development

Force enable or disable the Inspect Element menu item.

showServices

Type: boolean
Default: false

Show the system Services submenu when right-clicking text on macOS.

Note: Due to a bug in the Electron implementation, this menu is not identical to the "Services" submenu in the context menus of native apps. Instead, it looks the same as the "Services" menu in the main App Menu. For this reason, it is currently disabled by default.

labels

Type: object
Default: {}

Override labels for the default menu items. Useful for i18n.

The placeholder {selection} may be used in any label, and will be replaced by the currently selected text, trimmed to a maximum of 25 characters length. This is useful when localizing the Look Up “{selection}” menu item, but can also be used in custom menu items, for example, to implement a Search Google for “{selection}” menu item. If there is no selection, the {selection} placeholder will be replaced by an empty string. Normally this placeholder is only useful for menu items which will only be shown when there is text selected. This can be checked using visible: parameters.selectionText.trim().length > 0 when implementing a custom menu item, as shown in the usage example above.

Format:

{
	labels: {
		copy: 'Copiar',
		saveImageAs: 'Guardar imagen como…',
		lookUpSelection: 'Consultar “{selection}”'
	}
}

shouldShowMenu

Type: Function

Determines whether or not to show the menu. Can be useful if you for example have other code presenting a context menu in some contexts.

The second argument is this parameters object.

Example:

{
	// Doesn't show the menu if the element is editable
	shouldShowMenu: (event, parameters) => !parameters.isEditable
}

menu

Type: Function

This option lets you manually pick what menu items to include. It's meant for advanced needs. The default menu with the other options should be enough for most use-cases, and it ensures correct behavior, for example, correct order of menu items. So prefer the append and prepend option instead of menu whenever possible.

The function passed to this option is expected to return MenuItem[]. The first argument the function receives is an array of default actions that can be used. These actions are functions that can take an object with a transform property (except for separator and inspect). The transform function will be passed the content of the action and can modify it if needed. If you use transform on cut, copy, or paste, they will convert rich text to plain text. The second argument is this parameters object. The third argument is the BrowserWindow the context menu was requested for. The fourth argument is an Array of menu items for dictionary suggestions. This should be used if you wish to implement spellcheck in your custom menu. The last argument is the context menu event.

Even though you include an action, it will still only be shown/enabled when appropriate. For example, the saveImage action is only shown when right-clicking an image.

MenuItem labels may contain the placeholder {selection} which will be replaced by the currently selected text as described in options.labels.

To get spellchecking, “Correct Automatically”, and “Learn Spelling” in the menu, please enable the spellcheck preference in browser window: new BrowserWindow({webPreferences: {spellcheck: true}})

The following options are ignored when menu is used:

  • showLookUpSelection
  • showCopyImage
  • showCopyImageAddress
  • showSaveImageAs
  • showSaveLinkAs
  • showInspectElement
  • showServices
  • showSearchWithGoogle

Default actions:

  • spellCheck
  • learnSpelling
  • separator
  • lookUpSelection
  • searchWithGoogle
  • cut
  • copy
  • paste
  • saveImage
  • saveImageAs
  • copyImage
  • copyImageAddress
  • copyLink
  • saveLinkAs
  • inspect
  • services

Example for actions:

{
	menu: (actions, props, browserWindow, dictionarySuggestions) => [
		...dictionarySuggestions,
		actions.separator(),
		actions.copyLink({
			transform: content => `modified_link_${content}`
		}),
		actions.separator(),
		{
			label: 'Unicorn'
		},
		actions.separator(),
		actions.copy({
			transform: content => `modified_copy_${content}`
		}),
		{
			label: 'Invisible',
			visible: false
		},
		actions.paste({
			transform: content => `modified_paste_${content}`
		})
	]
}

onShow

Type: Function

Called when the context menu is shown.

The function receives an Event object.

onClose

Type: Function

Called when the context menu is closed.

The function receives an Event object.

Related

Author: Sindresorhus
Source Code: https://github.com/sindresorhus/electron-context-menu 
License: MIT license

#electron #context #menu 

Electron-context-menu: Context Menu for Your Electron App
Nat  Grady

Nat Grady

1658417820

Debug-menu: Chrome-like Debugging Context Menu for Electron

debug-menu

Chrome-like "inspect element" context-menu for Electron

This module was extracted from electron-debug to keep it focused on its main features.

Context menu items

Inspect element

Inspect the clicked HTML element. It shows DevTools if it's not already opened.

Install

$ npm install --save-dev debug-menu

Usage

When you use this module in renderer process code, BrowserWindow instance need to be opened with node integration enabled.

We usually load this module only if the DEBUG environment variable is defined, to avoid end users of the app inadvertently opening DevTools.

const debugMenu = require('debug-menu');
debugMenu.install();  // activate context menu

// later, if needed
debugMenu.uninstall();  // deactivate context menu

API

debugMenu.install()

Activate context menu. This method add a listener on window DOM object contextmenu event.

debugMenu.middleware

Expose a middleware context menu that can be mounted with electron-contextmenu-middleware. See related example

debugMenu.uninstall()

Deactivate context menu. This method remove the listener on window object.

debugMenu.windowDebugMenu(win);

The debug Menu object template. You can use it to integrate with your own app context or BrowserWindow menu.

Arguments

  • win

BrowserWindow instance to use for this Menu.

Type: BrowserWindow
Default: the currently focused BrowserWindow.

Example

  // ... require electron module

  const debugMenu = require('debug-menu');
  const win = new BrowserWindow();

  const menu = Menu.buildFromTemplate([{
    label: 'Debug',
    submenu: debugMenu.windowDebugMenu(win)
  }]);

  if (process.platform !== 'darwin') {
    win.setMenu(menu);
  } else {
    electron.Menu.setApplicationMenu(menu);
  }

  // ... show window

Middleware example

  const debugMenu = require('debug-menu').middleware;
  const context = require('electron-contextmenu-middleware');

  context.use(debugMenu);

  context.activate();

Related projects

electron-contextmenu-middleware - Build electron context menus composing multiple middlewares functions.

electron-input-menu - Context menu for electron input elements.

Author: Parro-it
Source Code: https://github.com/parro-it/debug-menu 
License: MIT license

#electron #debug #menu 

Debug-menu: Chrome-like Debugging Context Menu for Electron
Rupert  Beatty

Rupert Beatty

1658343240

Laravel-menu: Html Menu Generator for Laravel

Html Menu Generator for Laravel

This is the Laravel version of our menu package adds some extras like convenience methods for generating URLs and macros.

Upgrading from version 1? There's a guide for that!

Menu::macro('main', function () {
    return Menu::new()
        ->action('HomeController@index', 'Home')
        ->action('AboutController@index', 'About')
        ->action('ContactController@index', 'Contact')
        ->setActiveFromRequest();
});
<nav class="navigation">
    {!! Menu::main() !!}
</nav>

Spatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects on our website.

Installation

You can install the package via composer:

composer require spatie/laravel-menu

Usage

Documentation is available at https://spatie.be/docs/menu.

Changelog

Please see CHANGELOG for more information what has changed recently.

Testing

$ phpunit

Contributing

Please see CONTRIBUTING for details.

Security

If you've found a bug regarding security please mail security@spatie.be instead of using the issue tracker.

Documentation is available at https://spatie.be/docs/menu.

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Credits

Author: Spatie
Source Code: https://github.com/spatie/laravel-menu 
License: MIT license

#laravel #html #php #menu 

Laravel-menu: Html Menu Generator for Laravel
Nat  Grady

Nat Grady

1657747560

Menubar: High Level Way to Create Menubar Desktop Apps with Electron

 ➖ Menubar

High level way to create menubar desktop applications with Electron.

This module provides boilerplate for setting up a menubar application using Electron. All you have to do is point it at your index.html and menubar will handle the rest.

✅ Only one dependency, and one peer-dependency.

✅ Works on macOS, Windows and most Linuxes. See details.

✅ 💥 3.6kB minified + gzipped 💥

macOS Mojave 10.14Windows 10Ubuntu 18.04

Installation

yarn add menubar

Usage

Starting with your own new project, run these commands:

$ yarn add menubar
$ touch myApp.js
$ touch index.html

Fill index.html with some HTML, and myApp.js like this:

const { menubar } = require('menubar');

const mb = menubar();

mb.on('ready', () => {
  console.log('app is ready');
  // your app code here
});

Then use electron to run the app:

$ electron myApp.js

Alternatively, see examples/hello-world folder for a simple working example.

Menubar Class

The return value of menubar() is a Menubar class instance, which has these properties:

  • app: the Electron App instance,
  • window: the Electron Browser Window instance,
  • tray: the Electron Tray instance,
  • positioner: the Electron Positioner instance,
  • setOption(option, value): change an option after menubar is created,
  • getOption(option): get an menubar option,
  • showWindow(): show the menubar window,
  • hideWindow(): hide the menubar window

See the reference API docs.

menubar() Options

You can pass an optional options object into the menubar({ ... }) function:

  • dir (default process.cwd()) - the app source directory
  • index (default file:// + opts.dir + index.html) - The URL to load the menubar's browserWindow with. The url can be a remote address (e.g. http://) or a path to a local HTML file using the file:// protocol.
  • browserWindow - BrowserWindow options to be passed to the BrowserWindow constructor, see Electron docs. Some interesting fields to passed down are:
    • x (default undefined) - the x position of the window
    • y (default undefined) - the y position of the window
    • width (default 400) - window width
    • height (default 400) - window height
    • alwaysOnTop (default false) - if true, the window will not hide on blur
  • icon (default opts.dir + IconTemplate.png) - the png icon to use for the menubar. A good size to start with is 20x20. To support retina, supply a 2x sized image (e.g. 40x40) with @2x added to the end of the name, so icon.png and icon@2x.png and Electron will automatically use your @2x version on retina screens.
  • tooltip (default empty) - menubar tray icon tooltip text
  • tray (default created on-the-fly) - an electron Tray instance. if provided opts.icon will be ignored
  • preloadWindow (default false) - Create BrowserWindow instance before it is used -- increasing resource usage, but making the click on the menubar load faster.
  • loadUrlOptions - (default undefined) The options passed when loading the index URL in the menubar's browserWindow. Everything browserWindow.loadURL supports is supported; this object is simply passed onto browserWindow.loadURL
  • showOnAllWorkspaces (default true) - Makes the window available on all OS X workspaces.
  • windowPosition (default trayCenter and trayBottomCenter on Windows) - Sets the window position (x and y will still override this), check positioner docs for valid values.
  • showDockIcon (default false) - Configure the visibility of the application dock icon.
  • showOnRightClick (default false) - Show the window on 'right-click' event instead of regular 'click'

See the reference API docs.

Events

The Menubar class is an event emitter:

  • ready - when menubar's tray icon has been created and initialized, i.e. when menubar is ready to be used. Note: this is different than Electron app's ready event, which happens much earlier in the process
  • create-window - the line before new BrowserWindow() is called
  • before-load - after create window, before loadUrl (can be used for require("@electron/remote/main").enable(webContents))
  • after-create-window - the line after all window init code is done and url was loaded
  • show - the line before window.show() is called
  • after-show - the line after window.show() is called
  • hide - the line before window.hide() is called (on window blur)
  • after-hide - the line after window.hide() is called
  • after-close - after the .window (BrowserWindow) property has been deleted
  • focus-lost - emitted if always-on-top option is set and the user clicks away

Compatibility with Electron

menubarElectronNotes
9.x.x9.x.x | 10.x.x | 11.x.x | 12.x.x | 13.x.x | 14.x.x | 15.x.x | 16.x.x | 17.x.x | 18.x.x | 19.x.x 
8.x.x8.x.x 
7.x.x7.x.x 
6.x.x4.x.x | 5.x.x | 6.x.xNot recommended for security reasons
<= 5.x.x<= 3.x.xPlease, please don't use these old versions

API Docs

See the reference API docs.

Tips

  • Use mb.on('after-create-window', callback) to run things after your app has loaded. For example you could run mb.window.openDevTools() to open the developer tools for debugging, or load a different URL with mb.window.loadURL()
  • Use mb.on('focus-lost') if you would like to perform some operation when using the option browserWindow.alwaysOnTop: true
  • To restore focus of previous window after menubar hide, use mb.on('after-hide', () => { mb.app.hide() } ) or similar
  • To create a native menu, you can use tray.setContextMenu(contextMenu), and pass this custom tray to menubar: const mb = menubar({ tray });. See this example for more information.
  • To avoid a flash when opening your menubar app, you can disable backgrounding the app using the following: mb.app.commandLine.appendSwitch('disable-backgrounding-occluded-windows', 'true');

Author: Maxogden
Source Code: https://github.com/maxogden/menubar 
License: BSD-2-Clause license

#electron #menu #desktop #typescript 

Menubar: High Level Way to Create Menubar Desktop Apps with Electron
Nat  Grady

Nat Grady

1657549980

Minira: Menubar App for JIRA

Menubar app for JIRA

Minira is built on top of Electron, Menubar and Angular 2. It is not a replacement for JIRA:s web interface, the goal is to list a number of important issues for the moment and have easy access to edit them.

minira.app

The name?

Jira is coming from the Japanese word for Godzilla, Gojira. Minira is the Japanese word for Minilla, Godzillas adopted son. 🎆

Development

js-standard-style

Clone this repo and:

npm install

Build:

webpack

Build the .app:

npm run build

Author: jenslind
Source Code: https://github.com/jenslind/minira 
License: MIT

#electron #javascript #angular #menu 

Minira: Menubar App for JIRA
Nat  Grady

Nat Grady

1657418400

Docker-indicator: Shows Docker's Status in The Menu Bar

docker-indicator

Shows an icon in the menu bar with the status of docker and a simple menu to start/stop containers.

Why?

I often forget if docker is running and this gives a quick visual.

Status

Running (can make a connection)

images/up.png

Not running (or at least cannot connect to one)

images/down.png

It can take a few seconds to update the status if connecting to a docker machine instance

Started container list (shows on top)

images/started-container.png

Stopped container list

images/stopped-containers.png

Usage

A dmg is provided in the releases. Otherwise, in the source directory start with npm start.

Connection

In version 0.1.0 a .docker-indicator.yaml file in your home directory is optional. If no file is found, the default socket at /var/run/docker.sock is used.

If connecting to a docker machine instance not available via a socket.

docker:
    protocol: https
    ip: 192.168.99.100
    port: 2376
    ca: /Users/user/.docker/machine/machines/default/ca.pem
    cert: /Users/user/.docker/machine/machines/default/cert.pem
    key: /Users/user/.docker/machine/machines/default/key.pem

Icon

Whale by Aditya Dipankar from the Noun Project

Changelog

0.3.0

  • Updated dependencies
  • Fixed #11, #10, #4

0.2.1

  • Fix socket location with Docker 1.11.1

0.2.0

  • Show better network address

0.1.0

  • Use socket by default
  • Update dependencies (electron 0.36.12 amoungst others)

0.0.4

  • Bug fixes for UI updates
  • OS X build

0.0.3

  • New icons
  • UI updates appropriately

0.0.2

  • Try to connect to docker smartly

0.0.1

  • UI reacts to Docker events
  • Start/Stop buttons work on containers

Author: khornberg
Source Code: https://github.com/khornberg/docker-indicator 
License: Apache-2.0 license

#electron #docker #menu #javascript 

Docker-indicator: Shows Docker's Status in The Menu Bar
Nat  Grady

Nat Grady

1657354579

Monu: Menubar Process Monitor Mac App [ALPHA]

Monu

Monu is an open source process monitoring menu bar application for Mac OS. You can configure Monu to launch programs, and when Monu starts up it will start them. Additionally, it will monitor the processes and restart them if they crash.

Monu is a portmanteau of 'monitor' and 'menu'. It has two C/C++ dependencies, Electron (which includes iojs) and the mon process monitor.

Monu is currently ALPHA STATUS and is intended for developers/early adopters.

To download the latest version visit the releases page

screenshot.png

How to use Monu

To configure Monu, click 'Open Config Folder' and open 'config.json' in a text editor. When you save and return to Monu your new configuration will be automatically loaded.

Be sure your JSON syntax is valid when editing the configuration. Here are supported options. These should be added as top level key/value pairs to 'config.json':

  • processes the processes to run (see below)
  • logs the directory to store logs in (default config/logs)
  • pids the directory to store PIDs in (default config/pids)
  • on-error a command to run when a process cannot start (default none)
  • on-restart a command to run when a process restarts (default none)
  • sleep sleep seconds before re-executing (default 1)
  • attempts restart attempts within 60 seconds before stopping app (default 10)
  • prefix add a string prefix to the log (default none)

Adding Processes

In the 'config.json' file add processes to the 'processes' key. The key must be a name (lowercase letters and hypens) and the value must be the launch command. For example:

{
  "logs": "./logs",
  "pids": "./pids",
  "processes": {
    "web-1": "http-server . -p 8081",
    "web-2": "http-server . -p 8082",
    "web-3": "http-server . -p 8083"
  }
}

Launch on Startup

When you open Monu.app, it will start all configured processes.

If you would like Monu.app to start when your Mac starts up, got to System Preferences > Users and Groups and add Monu.app to Login Items for your User.

Developing

npm install # installs electron and all the deps needed for monu npm start # runs the app in the electron wrapper npm run build # builds the mac app

Publishing

Before publishing, make sure that your repo is clean, and that you've created a tag for the latest commit. npm version [major|minor|patch] will do this for you, increasing the package.json version, creating a commit and adding a tag.

You should see something like this:

🐈  make publish
rm -rf Monu.app Monu.zip # prevent duplicates in the final bundle
npm run build

> monu@1.0.4 build /Users/maxogden/src/js/monu
> electron-packager . Monu --platform=darwin --arch=x64 --version=0.26.0 --ignore=node_modules/electron

Wrote new app to /Users/maxogden/src/js/monu/Monu.app
ditto -c -k --sequesterRsrc --keepParent Monu.app Monu.zip
npm run publish

> monu@1.0.4 publish /Users/maxogden/src/js/monu
> publish-release --template notes.md --assets Monu.zip

? Git Tag: v1.0.4
? Github repository owner: maxogden
? Github repository name: monu
? Release Name: Monu v1.0.4 Alpha

Uploading Monu.zip
[=================================================>] 100.0% (1.17 MB/s)
Done! Published at: https://github.com/maxogden/monu/releases/tag/v1.0.4

Author: Maxogden
Source Code: https://github.com/maxogden/monu 
License: BSD-2-Clause license

#electron #menu #mac #javascript #css 

Monu: Menubar Process Monitor Mac App [ALPHA]
Nat  Grady

Nat Grady

1657282620

Piglet: Run Grunt Tasks From OS X Menubar

Piglet

Run Grunt tasks from OS X menubar.

Select your source dir and then run Grunt tasks from the menubar.

Install

Download and extract.

Build

npm run build

Test

npm test

Author: jenslind
Source Code: https://github.com/jenslind/piglet 
License: MIT license

#electron #javascript #menu 

Piglet: Run Grunt Tasks From OS X Menubar
Nat  Grady

Nat Grady

1657277220

A Tiny App That Shows ITunes Current Playing Song on Mac Menu Bar

Kyoku

A tiny app that shows iTunes current playing song on Mac menu bar.

Screenshot

To download the latest version, visit the releases page.

Development

  1. npm install
  2. npm start to launch the app
  3. npm run package to package the app
  4. npm run zip to zip the app package

TODO

  •  Show Album and Artist info in the menu
  •  Have a preference for setting custom maximum number of characters for song title
  •  Have a nice icon
  •  Windows version?

Icon

The music note icon is made by Freepik from www.flaticon.com and licensed by CC BY 3.0.

Author: Cheeaun
Source Code: https://github.com/cheeaun/kyoku 
License:  MIT

#electron #javascript #menu 

A Tiny App That Shows ITunes Current Playing Song on Mac Menu Bar
Nat  Grady

Nat Grady

1657275240

OSX: A Tiny Os X Menubar App to Display The Upcoming Events

webuild sg menubar

a tiny OS X menubar app to display the upcoming events and recently updated repos from webuild.sg

features

  1. fetch updated list of events and repositories every hour
  • create osx notification if there are events upcoming in the next hour
  • create osx notification if the top repository changes

getting started

  1. download the latest app and move it to your Applications folder.
  • double-click to open the menubar app

install

  1. install packages
npm i

run the app from command line without building it

npm start

build the app to create WeBuildSG.app.zip

npm run build

credits

  1. menubar

Author: Webuildsg
Source Code: https://github.com/webuildsg/osx 
License: MIT license

#electron #javascript #menu 

OSX: A Tiny Os X Menubar App to Display The Upcoming Events
Nat  Grady

Nat Grady

1657224720

Cumulus: A SoundCloud Player That Lives in Your Menubar

Cumulus

A SoundCloud player that lives in your menubar.

Installing

Download the latest release for OSX.

IntelliJ users be warned: This app hijacks the ⌘+Alt+L shortcurt used by IntelliJ to reformat code. See 40 and 77.

Developing

Install dependencies

npm install

npm install -g electron

Compile the application

grunt or grunt build

Run the application with the Chrome DevTools

NODE_ENV=development electron .

Or in Windows:

  • PowerShell: $env:NODE_ENV="development"; electron .
  • CMD: set "NODE_ENV=development" & electron .

Author: gillesdemey
Source Code: https://github.com/gillesdemey/Cumulus 
License: MIT license

#electron #menu #javascript 

Cumulus: A SoundCloud Player That Lives in Your Menubar