Skip to content
Draft
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
7 changes: 4 additions & 3 deletions lib/consts.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:ce_mobile/model/workspace.dart';
import 'package:ce_mobile/model/compiler.dart';
import 'package:ce_mobile/model/language.dart';

// Default URL
const String defaultUrl = 'https://godbolt.org';
Expand All @@ -10,7 +11,7 @@ const String compileEndpoint = '/api/compiler';

// Default
const Compiler defaultCompiler =
Compiler.create('g132', 'x86-64 gcc 13.2', 'c++', '', '13.2', 'amd64');
Compiler('g132', 'x86-64 gcc 13.2', 'c++', '', '13.2', 'amd64');

const Language defaultLanguage = Language.create('c++', 'C++',
const Language defaultLanguage = Language('c++', 'C++',
['.cpp', '.cxx', '.h', '.hpp', '.hxx', '.c', '.cc', '.ixx'], 'cppp');
49 changes: 49 additions & 0 deletions lib/model/compiler.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import 'dart:io';

import 'package:ce_mobile/consts.dart';
import 'package:dart_json_mapper/dart_json_mapper.dart';
import 'package:http/http.dart' as http;

@jsonSerializable
class Compiler {
final String id;
final String name;
final String lang;
final String compilerType;
final String semver;
final String instructionSet;

const Compiler(this.id, this.name, this.lang, this.compilerType, this.semver,
this.instructionSet);

static Future<List<Compiler>> fetchCompilers() async {
final response = await http.get(Uri.parse('$defaultUrl$compilersEndpoint'),
headers: <String, String>{
HttpHeaders.acceptHeader: 'application/json'
});

if (response.statusCode == HttpStatus.ok) {
return JsonMapper.deserialize<List<Compiler>>(response.body)
as List<Compiler>;
} else {
throw Exception('Failed to fetch compilers: ${response.statusCode}');
}
}

static Future<List<Compiler>> fetchCompilersForLanguage(
String langName) async {
final response = await http.get(
Uri.parse('$defaultUrl$compilersEndpoint/$langName'),
headers: <String, String>{
HttpHeaders.acceptHeader: 'application/json'
});

if (response.statusCode == HttpStatus.ok) {
return JsonMapper.deserialize<List<Compiler>>(response.body)
as List<Compiler>;
} else {
throw Exception(
'Failed to fetch compilers for $langName: ${response.statusCode}');
}
}
}
29 changes: 29 additions & 0 deletions lib/model/language.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import 'dart:io';

import 'package:ce_mobile/consts.dart';
import 'package:dart_json_mapper/dart_json_mapper.dart';
import 'package:http/http.dart' as http;

@jsonSerializable
class Language {
final String id;
final String name;
final List<String> extensions;
final String monaco;

const Language(this.id, this.name, this.extensions, this.monaco);

static Future<List<Language>> fetchLanguages() async {
final response = await http.get(Uri.parse('$defaultUrl$languagesEndpoint'),
headers: <String, String>{
HttpHeaders.acceptHeader: 'application/json'
});

if (response.statusCode == HttpStatus.ok) {
return JsonMapper.deserialize<List<Language>>(response.body)
as List<Language>;
} else {
throw Exception('Failed to fetch languages: ${response.statusCode}');
}
}
}
94 changes: 9 additions & 85 deletions lib/model/workspace.dart
Original file line number Diff line number Diff line change
@@ -1,96 +1,20 @@
import 'dart:developer';
import 'dart:io';

import 'package:http/http.dart' as http;
import 'package:ce_mobile/consts.dart';
import 'package:ce_mobile/model/compiler.dart';
import 'package:ce_mobile/model/language.dart';
import 'package:dart_json_mapper/dart_json_mapper.dart';
import 'package:isar/isar.dart';

part 'workspace.g.dart';
import 'package:uuid/uuid.dart';

@jsonSerializable
@embedded
class Compiler {
final String id;
final String name;
final String lang;
final String compilerType;
final String semver;
final String instructionSet;

const Compiler.create(this.id, this.name, this.lang, this.compilerType, this.semver,
this.instructionSet);

Compiler() : id = '', name = '', lang = '', compilerType = '', semver = '', instructionSet = '';

static Future<List<Compiler>> fetchCompilers() async {
final response = await http.get(Uri.parse('$defaultUrl$compilersEndpoint'),
headers: <String, String>{
HttpHeaders.acceptHeader: 'application/json'
});

if (response.statusCode == HttpStatus.ok) {
return JsonMapper.deserialize<List<Compiler>>(response.body) as List<Compiler>;
} else {
throw Exception('Failed to fetch compilers: ${response.statusCode}');
}
}

static Future<List<Compiler>> fetchCompilersForLanguage(
String langName) async {
final response = await http.get(
Uri.parse('$defaultUrl$compilersEndpoint/$langName'),
headers: <String, String>{
HttpHeaders.acceptHeader: 'application/json'
});

if (response.statusCode == HttpStatus.ok) {
return JsonMapper.deserialize<List<Compiler>>(response.body) as List<Compiler>;
} else {
throw Exception(
'Failed to fetch compilers for $langName: ${response.statusCode}');
}
}
}

@jsonSerializable
@embedded
class Language {
final String id;
final String name;
final List<String> extensions;
final String monaco;

Language() : id = '', name = '', extensions = List.empty(), monaco = '';

const Language.create(this.id, this.name, this.extensions, this.monaco);

static Future<List<Language>> fetchLanguages() async {
final response = await http.get(Uri.parse('$defaultUrl$languagesEndpoint'), headers: <String, String>{ HttpHeaders.acceptHeader: 'application/json' });

if (response.statusCode == HttpStatus.ok) {
return JsonMapper.deserialize<List<Language>>(response.body) as List<Language>;
} else {
throw Exception('Failed to fetch languages: ${response.statusCode}');
}
}
}

@embedded
class WorkspaceFile {
String filename;
String code;

WorkspaceFile() : filename = '', code = '' {
log('WorkspaceFile empty constructor was called from:\n${StackTrace.current}');
}

WorkspaceFile.create(this.filename, this.code);
WorkspaceFile(this.filename, this.code);
}

@collection
@jsonSerializable
class Workspace {
Id id = Isar.autoIncrement;
String uuid;

String name;
Compiler currentCompiler;
Expand All @@ -100,10 +24,10 @@ class Workspace {

late List<WorkspaceFile> files;

@ignore
@JsonProperty(ignore: true)
bool saveOnDisk;

Workspace(this.name, {this.saveOnDisk = true}) : currentCompiler = defaultCompiler, currentLanguage = defaultLanguage {
files = List.of([WorkspaceFile.create('main${currentLanguage.extensions.first}', '')]);
Workspace(this.name, {this.saveOnDisk = true}) : currentCompiler = defaultCompiler, currentLanguage = defaultLanguage, uuid = const Uuid().v4() {
files = List.of([WorkspaceFile('main${currentLanguage.extensions.first}', '')]);
}
}
7 changes: 3 additions & 4 deletions lib/pages/editor_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'dart:developer';

import 'package:ce_mobile/model/workspace.dart';
import 'package:ce_mobile/services/ce_service.dart';
import 'package:ce_mobile/services/isar_service.dart';
import 'package:ce_mobile/services/sembast_service.dart';
import 'package:ce_mobile/widgets/code_editor.dart';
import 'package:flutter/material.dart';

Expand All @@ -16,7 +16,7 @@ class EditorPage extends StatefulWidget {
}

class _EditorPageState extends State<EditorPage> {
final IsarService _service = IsarService();
final SembastService _service = SembastService();

// late PageController _pageController;

Expand Down Expand Up @@ -55,15 +55,14 @@ class _EditorPageState extends State<EditorPage> {
return PopScope(
onPopInvoked: (didPop) {
widget.workspace.lastModified = DateTime.now();
log(widget.workspace.currentCompiler.name);
if (widget.workspace.saveOnDisk) {
Future.wait([_service.saveWorkspace(widget.workspace)]);
}
},
child: Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text('Editor [${widget.workspace.name}] (${widget.workspace.currentCompiler.name})'),
title: Text('Editor [${widget.workspace.name}] (${widget.workspace.uuid})'),
),
body: PageView.builder(
itemCount: _pageCount,
Expand Down
62 changes: 40 additions & 22 deletions lib/pages/welcome_page.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'dart:developer';

import 'package:ce_mobile/services/isar_service.dart';
import 'package:ce_mobile/model/workspace.dart';
import 'package:ce_mobile/pages/editor_page.dart';
import 'package:ce_mobile/services/sembast_service.dart';
import 'package:ce_mobile/widgets/create_dialog.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
Expand All @@ -15,7 +15,7 @@ class WelcomePage extends StatefulWidget {
}

class _WelcomePageState extends State<WelcomePage> {
final IsarService isarService = IsarService();
final SembastService _service = SembastService();

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -73,31 +73,49 @@ class _WelcomePageState extends State<WelcomePage> {
style: TextStyle(decoration: TextDecoration.underline),
)),
StreamBuilder(
stream: isarService.streamRecentWorkspaces(),
stream: _service.streamRecentWorkspaces(),
builder: (context, snapshot) {
if (snapshot.hasData) {
final workspaces = snapshot.data;
if (workspaces != null) {
return Expanded(
child: ListView.builder(
itemCount: workspaces.length,
itemBuilder: (context, index) {
final workspace = workspaces[index];
if (workspaces.isNotEmpty) {
return Expanded(
child: ListView.builder(
itemCount: workspaces.length,
itemBuilder: (context, index) {
final workspace = workspaces[index];

return ListTile(
title: Text('${workspace.name} - ${workspace.currentCompiler.name} - ${workspace.files.first.filename}'),
subtitle: Text(
'Last modified: ${DateFormat('dd-MM-yyyy kk:mm').format(workspace.lastModified)}'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EditorPage(
workspace: workspace)));
},
);
}),
);
return ListTile(
title: Text(
'${workspace.name} - ${workspace.currentCompiler.name} - ${workspace.uuid}'),
subtitle: Text(
'Last modified: ${DateFormat('dd-MM-yyyy kk:mm').format(workspace.lastModified)}'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EditorPage(
workspace: workspace)));
},
);
}),
);
} else {
return Expanded(
child: Center(
child: Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
border: Border.all(
color: Theme.of(context).colorScheme.error)),
child: Text(
'You have no projects.',
style: TextStyle(
color: Theme.of(context).colorScheme.error,
),
),
)));
}
}
} else if (snapshot.hasError) {
log('Error: ${snapshot.error.toString()}');
Expand Down
6 changes: 3 additions & 3 deletions lib/services/ce_service.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import 'dart:io';

import 'package:ce_mobile/consts.dart';
import 'package:ce_mobile/model/compiler.dart';
import 'package:dart_json_mapper/dart_json_mapper.dart';

import '../consts.dart';
import '../model/workspace.dart';
import 'package:http/http.dart' as http;

@jsonSerializable
Expand Down Expand Up @@ -78,7 +78,7 @@ class CEService {
final json = JsonMapper.serialize(request);

final response = await http.post(
Uri.parse('$defaultUrl$compileEndpoint/g132/compile'),
Uri.parse('$defaultUrl$compileEndpoint/${cc.id}/compile'),
body: json,
headers: <String, String>{
HttpHeaders.contentTypeHeader: 'application/json',
Expand Down
31 changes: 0 additions & 31 deletions lib/services/isar_service.dart

This file was deleted.

Loading