Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# zine
DIY E-Zine and Operating System
# Zine OS

DIY E-Zine and Operating System

Interfaces
----------
==========

FS Interface
------------
Expand All @@ -24,14 +24,14 @@ Delete a file at a path, returns a promise that is fulfilled when the delete suc
Returns a promise

list: (directoryPath) ->


FileEntry Interface
------------------
-------------------

path:
size:
type:
path:
size:
type:

FolderEntry Interface
---------------------
Expand Down
6 changes: 3 additions & 3 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ System Features

[ ] Drag 'n' Drop

[ ] Cloud Briefcase
[X] Cloud Briefcase

Applications
------------
Expand Down Expand Up @@ -55,6 +55,6 @@ Network Social

[ ] Sharing

[ ] Remote Files
[ ] Remote Files (Network Neighborhood)

[ ] Personal Homepage
[X] Personal Homepage
15 changes: 15 additions & 0 deletions apps/achievement-status.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = ->
{Achievement, UI} = system
{Window} = UI

cheevoElement = Achievement.progressView()
cheevoElement.style.width = "100%"
cheevoElement.style.padding = "1em"

Achievement.unlock "Check yo' self"

windowView = Window
title: "Cheevos"
content: cheevoElement
width: 640
height: 480
12 changes: 10 additions & 2 deletions apps/audio-bro.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Model = require "model"

module.exports = ->
# Global system
{ContextMenu, MenuBar, Modal, Progress, Util:{parseMenu}, Window} = system.UI
{ContextMenu, MenuBar, Modal, Observable, Progress, Util:{parseMenu}, Window} = system.UI
{Achievement} = system

Achievement.unlock "Pump up the jam"
Expand All @@ -14,8 +14,11 @@ module.exports = ->
audio.controls = true
audio.autoplay = true

filePath = Observable()

handlers = Model().include(FileIO).extend
loadFile: (blob) ->
filePath blob.path
audio.src = URL.createObjectURL blob

exit: ->
Expand All @@ -31,11 +34,16 @@ module.exports = ->
handlers: handlers

windowView = Window
title: "Audio Bro"
title: ->
if path = filePath()
"Audio Bro - #{path}"
else
"Audio Bro"
content: audio
menuBar: menuBar.element
width: 308
height: 80
iconEmoji: "🎶"

windowView.loadFile = handlers.loadFile

Expand Down
1 change: 1 addition & 0 deletions apps/chateau.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = ->
width: 960
height: 540
title: "Chateau"
iconEmoji: "🍷"

app.on "event", (name) ->
switch name
Expand Down
6 changes: 2 additions & 4 deletions apps/contrasaurus.coffee
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
IFrameApp = require "../lib/iframe-app"

module.exports = ->
{Achievement} = system
{Achievement, iframeApp} = system

app = IFrameApp
app = iframeApp
src: "https://contrasaur.us/"
width: 960
height: 540
Expand Down
18 changes: 6 additions & 12 deletions apps/dungeon-of-sadness.coffee
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
Model = require "model"

module.exports = ->
{ContextMenu, MenuBar, Modal, Observable, Progress, Table, Util:{parseMenu}, Window} = system.UI

frame = document.createElement "iframe"
frame.src = "https://danielx.net/ld33/"
{Achievement, iframeApp} = system

system.Achievement.unlock "The dungeon is in our heart"

windowView = Window
app = iframeApp
title: "Dungeon of Sadness"
content: frame
menuBar: null
src: "https://danielx.net/ld33/"
width: 648
height: 507

return windowView
Achievement.unlock "The dungeon is in our heart"

return app
90 changes: 65 additions & 25 deletions apps/explorer.coffee
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# Explorer File Browser
#
# Explore the file system like adventureres of old!
# TODO: Drag and drop folders between folders
# TODO: Drop files onto folders
# TODO: Drop files onto applications
# TODO: Select multiple
# TOOD: Keyboard Input
Expand All @@ -13,21 +11,40 @@ FolderTemplate = require "../templates/folder"

{emptyElement} = require "../util"

extractPath = (element) ->
while element
path = element.getAttribute("path")
return path if path
element = element.parentElement

module.exports = Explorer = (options={}) ->
{ContextMenu, MenuBar, Modal, Progress, Util:{parseMenu}, Window} = system.UI
{path} = options
path ?= '/'

explorer = document.createElement "explorer"
explorer.setAttribute("path", path)

Drop explorer, (e) ->
return if e.defaultPrevented

targetPath = extractPath(e.target) or path
folderTarget = targetPath.match(/\/$/)

fileSelectionData = e.dataTransfer.getData("zineos/file-selection")

if fileSelectionData
data = JSON.parse fileSelectionData
system.moveFileSelection(data, path)

if folderTarget
system.moveFileSelection(data, targetPath)
else
# Attempt to open file in app
selectedFile = data.files[0]
console.log "Open in app #{targetPath} <- #{selectedFile}"
system.readFile(selectedFile.path)
.then (file) ->
system.execPathWithFile(targetPath, file)
e.preventDefault()

return
Expand All @@ -36,9 +53,13 @@ module.exports = Explorer = (options={}) ->

if files.length
e.preventDefault()
files.forEach (file) ->
newPath = path + file.name
system.writeFile(newPath, file, true)
if folderTarget
files.forEach (file) ->
newPath = targetPath + file.name
system.writeFile(newPath, file, true)
else
file = files[0]
system.execPathWithFile(targetPath, file)

explorerContextMenu = ContextMenu
items: parseMenu """
Expand Down Expand Up @@ -150,10 +171,24 @@ module.exports = Explorer = (options={}) ->
handlers:
open: ->
addWindow(folder.path)
delete: -> # TODO: Delete all files under folder
delete: ->
system.readTree(folder.path)
.then (results) ->
Promise.all results.map (result) ->
system.deleteFile(result.path)
rename: ->
;# TODO: Rename all files under folder (!)
# May want to think about inodes or something that makes this simpler
Modal.prompt "Name", folder.path
.then (newName) ->
return unless newName

# Ensure trailing slash
newName = newName.replace(/\/*$/, "/")

system.readTree(folder.path)
.then (files) ->
Promise.all files.map (file) ->
newPath = file.path.replace(folder.path, newName)
system.moveFile(file.path, newPath)
properties: -> # TODO

contextMenu.display
Expand All @@ -169,22 +204,25 @@ module.exports = Explorer = (options={}) ->
addedFolders = {}

files.forEach (file) ->
if file.relativePath.match /\// # folder
folderPath = file.relativePath.replace /\/.*$/, ""
if file.relativePath.match /\/$/ # folder
folderPath = file.relativePath
addedFolders[folderPath] = true
return

file.dblclick = ->
system.open file
Object.assign file,
displayName: file.relativePath

file.contextmenu = (e) ->
contextMenuFor(file, e)
dblclick: ->
system.open file

file.dragstart = (e) ->
# Note: Blobs don't make it through the stringify
e.dataTransfer.setData "zineos/file-selection", JSON.stringify
sourcePath: path
files: [ file ]
contextmenu: (e) ->
contextMenuFor(file, e)

dragstart: (e) ->
# Note: Blobs don't make it through the stringify
e.dataTransfer.setData "zineos/file-selection", JSON.stringify
sourcePath: path
files: [ file ]

fileElement = FileTemplate file
if file.type.match /^image\//
Expand All @@ -199,15 +237,18 @@ module.exports = Explorer = (options={}) ->

Object.keys(addedFolders).reverse().forEach (folderName) ->
folder =
path: "#{path}#{folderName}/"
path: "#{path}#{folderName}"
relativePath: folderName
displayName: folderName.replace(/\/$/, "")
contextmenu: (e) ->
contextMenuForFolder(folder, e)
dblclick: ->
# Open folder in new window
addWindow(folder.path)
dragstart: (e) ->
console.log e, folder
e.dataTransfer.setData "zineos/file-selection", JSON.stringify
sourcePath: folder.path.slice(0, folder.path.length - folder.relativePath.length)
files: [ folder ]

folderElement = FolderTemplate folder
explorer.insertBefore(folderElement, explorer.firstChild)
Expand All @@ -220,9 +261,7 @@ module.exports = Explorer = (options={}) ->
system.fs.on "update", (path) -> update()

addWindow = (path) ->
element = document.createElement "container"

element.appendChild Explorer
element = Explorer
path: path

windowView = Window
Expand All @@ -231,6 +270,7 @@ module.exports = Explorer = (options={}) ->
menuBar: null
width: 640
height: 480
iconEmoji: "📂"

document.body.appendChild windowView.element

Expand Down
19 changes: 15 additions & 4 deletions apps/my-briefcase.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This depends on having the AWS library available:

This is where you can put the files that you want to access from the cloud.

They'll live in the whims-fs bucket under the path to your aws user id.
They'll live in the whimsy-fs bucket under the path to your aws user id.

The subdomain -> s3 proxy will have a map from simple names to the crazy ids.

Expand Down Expand Up @@ -48,8 +48,11 @@ module.exports = ->
system.Achievement.unlock "Oh no, my files!"

LoginTemplate = system.compileTemplate """
a#LoginWithAmazon(@click)
img(border="0" alt="Login with Amazon" src="https://images-na.ssl-images-amazon.com/images/G/01/lwa/btnLWA_gold_156x32.png" width="156" height="32")
span(style="text-align: center; padding: 0 2em;")
h1 My Briefcase
p= @description
a#LoginWithAmazon(@click)
img(border="0" alt="Login with Amazon" src="https://images-na.ssl-images-amazon.com/images/G/01/lwa/btnLWA_gold_156x32.png" width="156" height="32")
"""

LoadedTemplate = system.compileTemplate """
Expand Down Expand Up @@ -119,6 +122,13 @@ module.exports = ->
console.warn e, e.message

content LoginTemplate
description: ->
"""
Maintain access to your files across different machines. Publish
effortlessly to the internet. Your briefcase holds all of your hopes
and dreams in a magical cloud that is available anywhere there is an
internet connection. 💼
"""
click: ->
options = { scope : 'profile' }
amazon.Login.authorize options, (resp) ->
Expand All @@ -141,10 +151,11 @@ module.exports = ->
.then receivedCredentials

windowView = Window
title: "💼 My Briefcase 💼"
title: "My Briefcase"
width: 640
height: 480
content: content
iconEmoji: "💼"

return windowView

Expand Down
Loading