-
Notifications
You must be signed in to change notification settings - Fork 199
[Obsolete] Add Android Export feature #545
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?xml version='1.0' encoding='utf-8'?> | ||
<widget id="io.cordova.hellocordova" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"> | ||
<name>CodeWorld App</name> | ||
<description> | ||
CodeWorld App | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be more descriptive, right? Maybe "This application is exported from CodeWorld." or something? |
||
</description> | ||
<author href="https://code.world"> | ||
CodeWorld | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe set this to "CodeWorld User" so it doesn't seem like we're claiming authorship of student programs? |
||
</author> | ||
<content src="index.html" /> | ||
<access origin="*" /> | ||
<allow-intent href="http://*/*" /> | ||
<allow-intent href="https://*/*" /> | ||
<allow-intent href="tel:*" /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the purpose of all these allow-intent elements? |
||
<allow-intent href="sms:*" /> | ||
<allow-intent href="mailto:*" /> | ||
<allow-intent href="geo:*" /> | ||
<platform name="android"> | ||
<allow-intent href="market:*" /> | ||
<icon density="mdpi" src="res/icon/android/mipmap-mdpi/codeworld.png" /> | ||
<icon density="hdpi" src="res/icon/android/mipmap-hdpi/codeworld.png" /> | ||
<icon density="xhdpi" src="res/icon/android/mipmap-xhdpi/codeworld.png" /> | ||
<icon density="xxhdpi" src="res/icon/android/mipmap-xxhdpi/codeworld.png" /> | ||
<icon density="xxxhdpi" src="res/icon/android/mipmap-xxxhdpi/codeworld.png" /> | ||
</platform> | ||
<plugin name="cordova-plugin-whitelist" spec="^1.3.2" /> | ||
</widget> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
* { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a source header, which you can copy from other css files in the project (e.g., in web/css). |
||
-webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */ | ||
} | ||
|
||
body { | ||
-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */ | ||
-webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */ | ||
-webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */ | ||
background-color:#E4E4E4; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see a gray background color or gradient anywhere in the app. Does any of this matter? |
||
background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%); | ||
background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%); | ||
background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%); | ||
background-image:-webkit-gradient( | ||
linear, | ||
left top, | ||
left bottom, | ||
color-stop(0, #A7A7A7), | ||
color-stop(0.51, #E4E4E4) | ||
); | ||
background-attachment:fixed; | ||
font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The text in exported apps appears to be a serif font, so I'll assume this doesn't matter either? |
||
font-size:12px; | ||
height:100%; | ||
margin:0px; | ||
padding:0px; | ||
text-transform:uppercase; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly, this doesn't seem to matter. |
||
width:100%; | ||
} | ||
|
||
/* Portrait layout (default) */ | ||
.app { | ||
position:absolute; /* position in the center of the screen */ | ||
left:50%; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this? What text box is it talking about? |
||
top:30%; | ||
height:50px; /* text area height */ | ||
width:225px; /* text area width */ | ||
text-align:center; | ||
} | ||
|
||
canvas { | ||
position: relative; | ||
left: -50%; | ||
top: -50%; | ||
} | ||
|
||
.app-inner { | ||
position: relative; | ||
left: -50%; | ||
top: -50%; | ||
} | ||
|
||
/* Landscape layout (with min-width) */ | ||
@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) { | ||
.app { | ||
background-position:left center; | ||
padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */ | ||
margin:-90px 0px 0px -198px; /* offset vertical: half of image height */ | ||
/* offset horizontal: half of image width and text area width */ | ||
} | ||
} | ||
|
||
h1 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This h1, .event, and .event.* also seem to refer to things that don't exist. |
||
font-size:24px; | ||
font-weight:normal; | ||
margin:0px; | ||
overflow:visible; | ||
padding:0px; | ||
text-align:center; | ||
} | ||
|
||
.event { | ||
border-radius:4px; | ||
-webkit-border-radius:4px; | ||
color:#FFFFFF; | ||
font-size:12px; | ||
margin:0px 30px; | ||
padding:2px 0px; | ||
} | ||
|
||
.event.listening { | ||
background-color:#333333; | ||
display:block; | ||
} | ||
|
||
.event.received { | ||
background-color:#4B946A; | ||
display:none; | ||
} | ||
|
||
@keyframes fade { | ||
from { opacity: 1.0; } | ||
50% { opacity: 0.4; } | ||
to { opacity: 1.0; } | ||
} | ||
|
||
@-webkit-keyframes fade { | ||
from { opacity: 1.0; } | ||
50% { opacity: 0.4; } | ||
to { opacity: 1.0; } | ||
} | ||
|
||
.blink { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blink? What's blinking? |
||
animation:fade 3000ms infinite; | ||
-webkit-animation:fade 3000ms infinite; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=default,Array.prototype.find,Number.isFinite,Number.isInteger,console,console.log,document.head,performance.now"></script> | ||
<head> | ||
<title>CodeWorld</title> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does the title matter? If so, it should probably be set to the app name. If it doesn't, take it out? |
||
<style type="text/css"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I noticed a lot of JavaScript and CSS is copied and pasted from other files. Is that because you can't package those other files into the Android apk? That would be a shame. If possible, let's try to use the same code rather than copy. |
||
* { margin: 0; overflow: hidden } | ||
#screen { | ||
cursor: default; | ||
width: 100vw; | ||
height: 100vw; | ||
max-height: 100vh; | ||
max-width: 100vh; | ||
} | ||
</style> | ||
</head> | ||
<body style="text-align: center"> | ||
<canvas id="screen"></canvas> | ||
</body> | ||
<script type="text/javascript"> | ||
function addMessage(err, str) { | ||
if (window.parent && window.parent.addToMessage) { | ||
var message = window.parent.addToMessage(str); | ||
|
||
if (err) { | ||
var message = window.parent.document.getElementById('message'); | ||
message.classList.add('error'); | ||
} | ||
} else { | ||
console.log(str); | ||
} | ||
} | ||
|
||
function showCanvas() { | ||
if (!window.parent) { | ||
return; | ||
} | ||
|
||
var runner = window.parent.document.getElementById('runner'); | ||
if (!runner) { | ||
return; | ||
} | ||
|
||
runner.style.display = ''; | ||
runner.focus(); | ||
runner.contentWindow.focus(); | ||
} | ||
|
||
function start() { | ||
h$base_writeStdout = function(fd, fdo, buf, buf_offset, n, c) { | ||
addMessage(false, h$decodeUtf8(buf, n, buf_offset)); | ||
c(n); | ||
}; | ||
h$base_writeStderr = function(fd, fdo, buf, buf_offset, n, c) { | ||
addMessage(false, h$decodeUtf8(buf, n, buf_offset)); | ||
c(n); | ||
}; | ||
h$log = function() { | ||
var s = ''; | ||
for(var i=0;i<arguments.length;i++) { s = s + arguments[i]; } | ||
addMessage(false, s+'\n'); | ||
}; | ||
h$errorMsg = function(str) { | ||
for(var i=1;i<arguments.length;i++) { | ||
str = str.replace(/%s/, arguments[i]); | ||
} | ||
addMessage(true, '\n' + str); | ||
}; | ||
h$base_stdout_fd.write = h$base_writeStdout; | ||
h$base_stderr_fd.write = h$base_writeStderr; | ||
|
||
h$run(h$mainZCZCMainzimain); | ||
} | ||
|
||
function reportRuntimeError(err, str) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is dead code. There are no calls to reportRuntimeError any longer. |
||
if (window.parent.addToMessage) { | ||
var message = window.parent.addToMessage('\n' + str); | ||
|
||
if (err) { | ||
var message = window.parent.document.getElementById('message'); | ||
message.classList.add('error'); | ||
} | ||
} else { | ||
console.log(str); | ||
} | ||
} | ||
|
||
var loadScript = document.createElement('script'); | ||
loadScript.setAttribute('type', 'text/javascript'); | ||
loadScript.setAttribute('src', 'js/runjs.js'); | ||
loadScript.onload = function() { | ||
start(); | ||
}; | ||
document.head.appendChild(loadScript); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can just write this instead of this whole block:
|
||
</script> | ||
|
||
</html> | ||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. stray blank lines at the end. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,14 @@ export PATH=$BUILD/bin:$PATH | |
export LANG=${LANG:-C.UTF-8} | ||
export PREFIX=$BUILD | ||
|
||
export ANDROID_HOME=$BUILD/Android/Sdk | ||
export PATH=$BUILD/Android/Sdk/tools:$PATH | ||
export PATH=$BUILD/Android/Sdk/platform-tools:$PATH | ||
export PATH=$BUILD/Android/Sdk/tools/bin:$PATH | ||
export PATH=$BUILD/Android/Sdk/tools/lib:$PATH | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does lib really need to be in the path? That's weird. |
||
|
||
export PATH=$BUILD/Cordova/node_modules/cordova/bin:$PATH | ||
|
||
function run { | ||
OLD_PWD=$PWD | ||
cd $1 | ||
|
@@ -38,3 +46,4 @@ function run { | |
function cabal_install { | ||
cabal install --force-reinstalls --global --prefix=$BUILD $@ | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. stray blank line. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,9 @@ cwd=$(pwd) | |
|
||
source base.sh | ||
|
||
# Create Cordova template | ||
run ./android-template cordova build android | ||
|
||
run . cabal update | ||
|
||
# Install the codeworld-base and codeworld-api packages | ||
|
@@ -53,3 +56,4 @@ run . cabal_install ./codeworld-server \ | |
|
||
# Build the JavaScript client code for FunBlocks, the block-based UI. | ||
run . cabal_install --ghcjs ./funblocks-client | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. stray blank line |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
{-# LANGUAGE OverloadedStrings #-} | ||
|
||
{- | ||
Copyright 2017 The CodeWorld Authors. All rights reserved. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
-} | ||
|
||
module AndroidExport where | ||
|
||
import Data.Maybe | ||
import qualified Data.Map as M | ||
import System.Process | ||
import System.Directory | ||
import System.FilePath | ||
import qualified System.IO.Strict as ST | ||
import Text.HTML.TagSoup | ||
|
||
import Util | ||
|
||
buildAndroid :: BuildMode -> ProgramId -> AppProps -> IO () | ||
buildAndroid mode programId appProps = do | ||
let appName = fromJust $ M.lookup "appName" appProps | ||
initCordovaProject mode programId | ||
copySource mode programId | ||
setAppName mode programId appName | ||
buildApk mode programId | ||
return () | ||
|
||
initCordovaProject :: BuildMode -> ProgramId -> IO () | ||
initCordovaProject mode programId = do | ||
let rootDir = androidRootDir mode | ||
checkIfRootExists <- doesDirectoryExist rootDir | ||
if not checkIfRootExists | ||
then do | ||
createDirectory $ androidRootDir mode | ||
else return () | ||
let buildDir = androidBuildDir mode programId | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You need to build in a temp dir. Otherwise you'll risk kicking off simultaneous builds pointed at the same directory, and this can confuse things and cause weird bug reports. It has happened before. |
||
checkIfBuildExists <- doesDirectoryExist buildDir | ||
if not checkIfBuildExists | ||
then do | ||
checkIfParentExists <- doesDirectoryExist $ androidRootDir mode </> sourceParent programId | ||
if not checkIfParentExists | ||
then do | ||
createDirectory $ androidRootDir mode </> sourceParent programId | ||
copyDirIfExists "android-template" (androidRootDir mode </> sourceBase programId) | ||
else return () | ||
else return () | ||
|
||
copySource :: BuildMode -> ProgramId -> IO () | ||
copySource mode programId = | ||
copyFile | ||
(buildRootDir mode </> targetFile programId) | ||
(androidBuildDir mode programId </> "www" </> "js" </> "runjs.js") | ||
|
||
setAppName :: BuildMode -> ProgramId -> String -> IO () | ||
setAppName mode programId appName = do | ||
let configFileName = androidBuildDir mode programId </> "config.xml" | ||
configContents <- ST.readFile configFileName | ||
let tagSoup = parseTags configContents | ||
let newNameTag = [TagOpen "name" [], TagText appName] | ||
writeFile configFileName (renderTags $ newSoup tagSoup newNameTag) | ||
where newSoup soup insertTag = takeWhile nameId soup | ||
++ insertTag | ||
++ drop 2 (dropWhile nameId soup) | ||
nameId = (~/= ("<name>"::String)) | ||
|
||
buildApk :: BuildMode -> ProgramId -> IO () | ||
buildApk mode programId = do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You need to set a time limit, and kill the process if it exceeds the time limit. There's a utility for that at https://github.com/google/codeworld/blob/master/codeworld-compiler/src/Compile.hs#L203, but unfortunately it was moved from codeworld-server to codeworld-compiler, as part of another Summer of Haskell project. For now, feel free to copy it back into codeworld-server/src/Util.hs |
||
currwd <- getCurrentDirectory | ||
setCurrentDirectory $ androidBuildDir mode programId | ||
readProcess "cordova" ["build", "android"] "" | ||
setCurrentDirectory currwd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
io.cordova.hellocordova ???
Would there be a problem installing two of these? Maybe the id would need to have the program hash in it to disambiguate? But I'm not sure, because I'm not sure what this is used for.