Skip to content

Commit 4f57527

Browse files
Refactor app structure
1 parent 1d471af commit 4f57527

File tree

16 files changed

+363
-349
lines changed

16 files changed

+363
-349
lines changed

internal_filesystem/builtin/apps/com.micropythonos.appstore/assets/appstore.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import _thread
88

99
from mpos.apps import Activity, Intent
10+
from mpos.app import App
1011
import mpos.ui
1112
from mpos.package_manager import PackageManager
1213

@@ -63,7 +64,7 @@ def download_app_index(self, json_url):
6364
applist = json.loads(response.text)
6465
for app in json.loads(response.text):
6566
try:
66-
self.apps.append(mpos.apps.App(app["name"], app["publisher"], app["short_description"], app["long_description"], app["icon_url"], app["download_url"], app["fullname"], app["version"], app["category"], app["activities"]))
67+
self.apps.append(App(app["name"], app["publisher"], app["short_description"], app["long_description"], app["icon_url"], app["download_url"], app["fullname"], app["version"], app["category"], app["activities"]))
6768
except Exception as e:
6869
print(f"Warning: could not add app from {json_url} to apps list: {e}")
6970
# Remove duplicates based on app.name

internal_filesystem/builtin/apps/com.micropythonos.launcher/assets/launcher.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
import mpos.apps
1616
import mpos.ui
1717
from mpos.package_manager import PackageManager
18+
from mpos import Activity
1819

19-
class Launcher(mpos.apps.Activity):
20+
class Launcher(Activity):
2021

2122
def onCreate(self):
2223
print("launcher.py onCreate()")
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Re-export common classes for convenience
2+
from .app.app import App
3+
from .app.activity import Activity
4+
from .content.intent import Intent
5+
from .navigator import ActivityNavigator
6+
from .package_manager import PackageManager
7+
8+
# Optional: re-export activities
9+
from .app.activities.chooser import ChooserActivity
10+
from .app.activities.view import ViewActivity
11+
from .app.activities.share import ShareActivity
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from .app import App
2+
from .activity import Activity
3+
from .activities.chooser import ChooserActivity
4+
from .activities.view import ViewActivity
5+
from .activities.share import ShareActivity
6+
7+
__all__ = [
8+
"App", "Activity",
9+
"ChooserActivity", "ViewActivity", "ShareActivity"
10+
]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from .chooser import ChooserActivity
2+
from .view import ViewActivity
3+
from .share import ShareActivity
4+
5+
__all__ = ["ChooserActivity", "ViewActivity", "ShareActivity"]
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from ..activity import Activity
2+
3+
#from ..activity import Activity
4+
5+
#import mpos.app.activity
6+
7+
#import mpos.app.activity
8+
9+
#from mpos.app import Activity
10+
11+
import mpos.package_manager
12+
13+
class ChooserActivity(Activity):
14+
def __init__(self):
15+
super().__init__()
16+
17+
def onCreate(self):
18+
screen = lv.obj()
19+
# Get handlers from intent extras
20+
original_intent = self.getIntent().extras.get("original_intent")
21+
handlers = self.getIntent().extras.gepackage_managert("handlers", [])
22+
label = lv.label(screen)
23+
label.set_text("Choose an app")
24+
label.set_pos(10, 10)
25+
26+
for i, handler_name in enumerate(handlers):
27+
btn = lv.btn(screen)
28+
btn.set_user_data(f"handler_{i}")
29+
btn_label = lv.label(btn)
30+
btn_label.set_text(handler_name)
31+
btn.set_pos(10, 50 * (i + 1) + 10)
32+
btn.add_event_cb(lambda e, h=handler_name, oi=original_intent: self._select_handler(h, oi), lv.EVENT.CLICKED)
33+
self.setContentView(screen)
34+
35+
def _select_handler(self, handler_name, original_intent):
36+
for handler in mpos.package_manager.PackageManager.APP_REGISTRY.get(original_intent.action, []):
37+
if handler.__name__ == handler_name:
38+
original_intent.activity_class = handler
39+
navigator.startActivity(original_intent)
40+
break
41+
navigator.finish() # Close chooser
42+
43+
def onStop(self, screen):
44+
if self.getIntent() and self.getIntent().getStringExtra("destination") == "ChooserActivity":
45+
print("Stopped for Chooser")
46+
else:
47+
print("Stopped for other screen")
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from ..activity import Activity
2+
3+
class ShareActivity(Activity):
4+
def __init__(self):
5+
super().__init__()
6+
7+
def onCreate(self):
8+
screen = lv.obj()
9+
# Get text from intent (prefer extras.text, fallback to data)
10+
text = self.getIntent().extras.get("text", self.getIntent().data or "No text")
11+
label = lv.label(screen)
12+
label.set_user_data("share_label")
13+
label.set_text(f"Share: {text}")
14+
label.set_pos(10, 10)
15+
16+
btn = lv.btn(screen)
17+
btn.set_user_data("share_btn")
18+
btn_label = lv.label(btn)
19+
btn_label.set_text("Share")
20+
btn.set_pos(10, 50)
21+
btn.add_event_cb(lambda e: self._share_content(text), lv.EVENT.CLICKED)
22+
self.setContentView(screen)
23+
24+
def _share_content(self, text):
25+
# Dispatch to another app (e.g., MessagingActivity) or simulate sharing
26+
print(f"Sharing: {text}") # Placeholder for actual sharing
27+
# Example: Launch another share handler
28+
navigator.startActivity(Intent(action="share", data=text))
29+
navigator.finish() # Close ShareActivity
30+
31+
def onStop(self, screen):
32+
if self.getIntent() and self.getIntent().getStringExtra("destination") == "ShareActivity":
33+
print("Stopped for Share")
34+
else:
35+
print("Stopped for other screen")
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from ..activity import Activity
2+
3+
class ViewActivity(Activity):
4+
def __init__(self):
5+
super().__init__()
6+
7+
def onCreate(self):
8+
screen = lv.obj()
9+
# Get content from intent (prefer extras.url, fallback to data)
10+
content = self.getIntent().extras.get("url", self.getIntent().data or "No content")
11+
label = lv.label(screen)
12+
label.set_user_data("content_label")
13+
label.set_text(f"Viewing: {content}")
14+
label.center()
15+
self.setContentView(screen)
16+
17+
def onStart(self, screen):
18+
content = self.getIntent().extras.get("url", self.getIntent().data or "No content")
19+
for i in range(screen.get_child_cnt()):
20+
if screen.get_child(i).get_user_data() == "content_label":
21+
screen.get_child(i).set_text(f"Viewing: {content}")
22+
23+
def onStop(self, screen):
24+
if self.getIntent() and self.getIntent().getStringExtra("destination") == "ViewActivity":
25+
print("Stopped for View")
26+
else:
27+
print("Stopped for other screen")
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from mpos.navigator import ActivityNavigator
2+
3+
import mpos.ui
4+
5+
class Activity:
6+
7+
def __init__(self):
8+
self.intent = None # Store the intent that launched this activity
9+
self.result = None
10+
self._result_callback = None
11+
12+
def onCreate(self):
13+
pass
14+
def onStart(self, screen):
15+
pass
16+
def onResume(self, screen):
17+
pass
18+
def onPause(self, screen):
19+
pass
20+
def onStop(self, screen):
21+
pass
22+
def onDestroy(self, screen):
23+
pass
24+
25+
def setContentView(self, screen):
26+
mpos.ui.setContentView(self, screen)
27+
28+
def startActivity(self, intent):
29+
ActivityNavigator.startActivity(intent)
30+
31+
def startActivityForResult(self, intent, result_callback):
32+
ActivityNavigator.startActivityForResult(intent, result_callback)
33+
34+
def initError(self, e):
35+
print(f"WARNING: You might have inherited from Activity with a custom __init__() without calling super().__init__(). Got AttributeError: {e}")
36+
37+
def getIntent(self):
38+
try:
39+
return self.intent
40+
except AttributeError as e:
41+
self.initError(e)
42+
43+
def setResult(self, result_code, data=None):
44+
"""Set the result to be returned when the activity finishes."""
45+
try:
46+
self.result = {"result_code": result_code, "data": data or {}}
47+
except AttributeError as e:
48+
self.initError(e)
49+
50+
def finish(self):
51+
mpos.ui.back_screen()
52+
try:
53+
if self._result_callback and self.result:
54+
self._result_callback(self.result)
55+
self._result_callback = None # Clean up
56+
except AttributeError as e:
57+
self.initError(e)
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import ujson
2+
from ..content.intent import Intent # optional, if App uses Intent
3+
4+
5+
class App:
6+
def __init__(
7+
self,
8+
name="Unknown",
9+
publisher="Unknown",
10+
short_description="",
11+
long_description="",
12+
icon_url="",
13+
download_url="",
14+
fullname="Unknown",
15+
version="0.0.0",
16+
category="",
17+
activities=None,
18+
installed_path=None,
19+
):
20+
self.name = name
21+
self.publisher = publisher
22+
self.short_description = short_description
23+
self.long_description = long_description
24+
self.icon_url = icon_url
25+
self.download_url = download_url
26+
self.fullname = fullname
27+
self.version = version
28+
self.category = category
29+
self.activities = activities or []
30+
self.installed_path = installed_path
31+
32+
self.image = None
33+
self.image_dsc = None
34+
self.main_launcher_activity = self._find_main_launcher_activity()
35+
36+
def __str__(self):
37+
return f"App({self.name}, v{self.version}, {self.category})"
38+
39+
def _find_main_launcher_activity(self):
40+
for act in self.activities:
41+
if not act.get("entrypoint") or not act.get("classname"):
42+
continue
43+
for f in act.get("intent_filters", []):
44+
if f.get("action") == "main" and f.get("category") == "launcher":
45+
return act
46+
return None
47+
48+
def is_valid_launcher(self):
49+
return self.category == "launcher" and self.main_launcher_activity
50+
51+
@classmethod
52+
def from_manifest(cls, appdir):
53+
manifest_path = f"{appdir}/META-INF/MANIFEST.JSON"
54+
default = cls(installed_path=appdir)
55+
try:
56+
with open(manifest_path, "r") as f:
57+
data = ujson.load(f)
58+
except OSError:
59+
return default
60+
61+
return cls(
62+
name=data.get("name", default.name),
63+
publisher=data.get("publisher", default.publisher),
64+
short_description=data.get("short_description", default.short_description),
65+
long_description=data.get("long_description", default.long_description),
66+
icon_url=data.get("icon_url", default.icon_url),
67+
download_url=data.get("download_url", default.download_url),
68+
fullname=data.get("fullname", default.fullname),
69+
version=data.get("version", default.version),
70+
category=data.get("category", default.category),
71+
activities=data.get("activities", default.activities),
72+
installed_path=appdir,
73+
)

0 commit comments

Comments
 (0)