Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/PojavLauncher_iOS
Path: blob/main/Natives/PLLogOutputView.m
589 views
1
#import "PLLogOutputView.h"
2
#import "SurfaceViewController.h"
3
#import "utils.h"
4
5
@interface PLLogOutputView()<UITableViewDataSource, UITableViewDelegate>
6
@property(nonatomic) UITableView* logTableView;
7
@property(nonatomic) UINavigationBar* navigationBar;
8
@end
9
10
@implementation PLLogOutputView
11
static BOOL fatalErrorOccurred;
12
static NSMutableArray* logLines;
13
static PLLogOutputView* current;
14
15
- (instancetype)initWithFrame:(CGRect)frame {
16
frame.origin.y = frame.size.height;
17
self = [super initWithFrame:frame];
18
frame.origin.y = 0;
19
20
logLines = [NSMutableArray new];
21
self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
22
self.hidden = YES;
23
24
UINavigationItem *navigationItem = [[UINavigationItem alloc] init];
25
navigationItem.rightBarButtonItems = @[
26
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop
27
target:self action:@selector(actionToggleLogOutput)],
28
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemTrash
29
target:self action:@selector(actionClearLogOutput)]
30
];
31
self.navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, 44)];
32
self.navigationBar.items = @[navigationItem];
33
self.navigationBar.topItem.title = localize(@"game.menu.log_output", nil);
34
[self.navigationBar sizeToFit];
35
self.navigationBar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
36
37
self.logTableView = [[UITableView alloc] initWithFrame:frame];
38
//self.logTableView.allowsSelection = NO;
39
self.logTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
40
self.logTableView.backgroundColor = UIColor.clearColor;
41
self.logTableView.contentInset = UIEdgeInsetsMake(self.navigationBar.frame.size.height, 0, 0, 0);
42
self.logTableView.dataSource = self;
43
self.logTableView.delegate = self;
44
self.logTableView.layoutMargins = UIEdgeInsetsZero;
45
self.logTableView.rowHeight = 20;
46
self.logTableView.separatorInset = UIEdgeInsetsZero;
47
self.logTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
48
[self addSubview:self.logTableView];
49
[self addSubview:self.navigationBar];
50
51
canAppendToLog = YES;
52
[self actionStartStopLogOutput];
53
54
current = self;
55
return self;
56
}
57
58
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
59
return logLines.count;
60
}
61
62
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
63
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
64
65
if (cell == nil) {
66
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
67
cell.backgroundColor = UIColor.clearColor;
68
//cell.selectionStyle = UITableViewCellSelectionStyleNone;
69
cell.textLabel.font = [UIFont fontWithName:@"Menlo-Regular" size:16];
70
cell.textLabel.textColor = UIColor.whiteColor;
71
}
72
cell.textLabel.text = logLines[indexPath.row];
73
74
return cell;
75
}
76
77
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
78
[tableView deselectRowAtIndexPath:indexPath animated:NO];
79
80
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
81
NSString *line = cell.textLabel.text;
82
if (line.length == 0 || [line isEqualToString:@"\n"]) {
83
return;
84
}
85
86
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:line preferredStyle:UIAlertControllerStyleActionSheet];
87
alert.popoverPresentationController.sourceView = cell;
88
alert.popoverPresentationController.sourceRect = cell.bounds;
89
UIAlertAction *share = [UIAlertAction actionWithTitle:localize(localize(@"Share", nil), nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
90
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[line] applicationActivities:nil];
91
activityVC.popoverPresentationController.sourceView = _navigationBar;
92
activityVC.popoverPresentationController.sourceRect = _navigationBar.bounds;
93
[currentVC() presentViewController:activityVC animated:YES completion:nil];
94
}];
95
UIAlertAction *cancel = [UIAlertAction actionWithTitle:localize(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil];
96
[alert addAction:share];
97
[alert addAction:cancel];
98
[currentVC() presentViewController:alert animated:YES completion:nil];
99
}
100
101
- (void)actionClearLogOutput {
102
[logLines removeAllObjects];
103
[self.logTableView reloadData];
104
}
105
106
- (void)actionShareLatestlog {
107
NSString *latestlogPath = [NSString stringWithFormat:@"file://%s/latestlog.txt", getenv("POJAV_HOME")];
108
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[@"latestlog.txt",
109
[NSURL URLWithString:latestlogPath]] applicationActivities:nil];
110
activityVC.popoverPresentationController.sourceView = self.navigationBar;
111
activityVC.popoverPresentationController.sourceRect = self.navigationBar.bounds;
112
[currentVC() presentViewController:activityVC animated:YES completion:nil];
113
}
114
115
- (void)actionStartStopLogOutput {
116
canAppendToLog = !canAppendToLog;
117
UINavigationItem* item = self.navigationBar.items[0];
118
item.leftBarButtonItem =
119
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:
120
canAppendToLog ? UIBarButtonSystemItemPause : UIBarButtonSystemItemPlay
121
target:self action:@selector(actionStartStopLogOutput)];
122
}
123
124
- (void)actionToggleLogOutput {
125
if (fatalErrorOccurred) {
126
[UIApplication.sharedApplication performSelector:@selector(suspend)];
127
dispatch_group_leave(fatalExitGroup);
128
return;
129
}
130
131
UIViewAnimationOptions opt = self.hidden ? UIViewAnimationOptionCurveEaseOut : UIViewAnimationOptionCurveEaseIn;
132
[UIView transitionWithView:self duration:0.4 options:UIViewAnimationOptionCurveEaseOut animations:^(void){
133
CGRect frame = self.frame;
134
frame.origin.y = self.hidden ? 0 : frame.size.height;
135
self.hidden = NO;
136
self.frame = frame;
137
} completion: ^(BOOL finished) {
138
self.hidden = self.frame.origin.y != 0;
139
}];
140
}
141
142
+ (void)_appendToLog:(NSString *)line {
143
if (line.length == 0) {
144
return;
145
}
146
147
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:logLines.count inSection:0];
148
[logLines addObject:line];
149
UIView.animationsEnabled = NO;
150
[current.logTableView beginUpdates];
151
[current.logTableView
152
insertRowsAtIndexPaths:@[indexPath]
153
withRowAnimation:UITableViewRowAnimationNone];
154
[current.logTableView endUpdates];
155
UIView.animationsEnabled = YES;
156
157
[current.logTableView
158
scrollToRowAtIndexPath:indexPath
159
atScrollPosition:UITableViewScrollPositionBottom animated:NO];
160
}
161
162
+ (void)appendToLog:(NSString *)string {
163
dispatch_async(dispatch_get_main_queue(), ^(void){
164
NSArray *lines = [string componentsSeparatedByCharactersInSet:
165
NSCharacterSet.newlineCharacterSet];
166
for (NSString *line in lines) {
167
[self _appendToLog:line];
168
}
169
});
170
}
171
172
+ (void)handleExitCode:(int)code {
173
if (!current) return;
174
dispatch_async(dispatch_get_main_queue(), ^(void){
175
if (current.hidden) {
176
[current actionToggleLogOutput];
177
}
178
// Cleanup navigation bar
179
UINavigationBar *navigationBar = current.navigationBar;
180
navigationBar.topItem.title = [NSString stringWithFormat:
181
localize(@"game.title.exit_code", nil), code];
182
navigationBar.items[0].leftBarButtonItem = [[UIBarButtonItem alloc]
183
initWithBarButtonSystemItem:UIBarButtonSystemItemAction
184
target:current action:@selector(actionShareLatestlog)];
185
UIBarButtonItem *exitItem = navigationBar.items[0].rightBarButtonItems[0];
186
navigationBar.items[0].rightBarButtonItems = nil;
187
navigationBar.items[0].rightBarButtonItem = exitItem;
188
189
if (canAppendToLog) {
190
canAppendToLog = NO;
191
fatalErrorOccurred = YES;
192
return;
193
}
194
[current actionClearLogOutput];
195
[self _appendToLog:@"... (latestlog.txt)"];
196
NSString *latestlogPath = [NSString stringWithFormat:@"%s/latestlog.txt", getenv("POJAV_HOME")];
197
NSString *linesStr = [NSString stringWithContentsOfFile:latestlogPath
198
encoding:NSUTF8StringEncoding error:nil];
199
NSArray *lines = [linesStr componentsSeparatedByCharactersInSet:
200
NSCharacterSet.newlineCharacterSet];
201
202
// Print last 100 lines from latestlog.txt
203
for (int i = MAX(lines.count-100, 0); i < lines.count; i++) {
204
[self _appendToLog:lines[i]];
205
}
206
207
fatalErrorOccurred = YES;
208
});
209
}
210
211
@end
212
213